npm package: @hello-aria/embed
Description: Type-safe widget library with TypeScript support
Author: Aria
Latest version: 3.0.1

# Aria Embed: Widget Library

**AriaEmbed** is a type-safe, iframe-based widget library that allows Aria partners to easily embed secure and accessible modal interfaces for debtor invoice validation and payment method management. It handles cross-origin communication, accessibility, focus trapping, and success/error callbacks out of the box.

---

## 🚀 Installation

### Option 1: Package Manager

```bash
npm install @hello-aria/embed
# or
yarn add @hello-aria/embed
# or
pnpm add @hello-aria/embed
```

### Option 2: CDN

You can also include the widget directly via a CDN in your HTML page:

```html
<script src="https://cdn.jsdelivr.net/npm/@hello-aria/embed/dist/index.umd.js"></script>
<script>
    AriaEmbed.init({
        environment: 'sandbox', // or 'production'
        language: 'EN',
        styles: {
            '--color-primary': '#3b82f6'
        }
    })

    // Invoice validation
    AriaEmbed.invoiceValidation.render({
        contact: {
            email: 'debtor@email.com',
            firstName: 'Alice',
            lastName: 'Martin'
        },
        invoiceId: 'inv_12345',
        onSuccess: (payload) => console.log('Validated:', payload),
        onError: (error) => console.error('Validation error:', error)
    })

    // Payment method setup
    AriaEmbed.payment.render({
        debtor: {
            debtorId: 'debtor_123',
            debtorIdentifier: {
                country: 'FR',
                type: 'siren',
                value: '123456789'
            },
            debtorEmail: 'debtor@email.com'
        },
        paymentMethod: {
            type: 'SEPA_DIRECT_DEBIT',
            sepaDebitType: 'CORE'
        },
        onSuccess: (payload) => console.log('Payment method configured:', payload),
        onError: (error) => console.error('Payment error:', error)
    })
</script>
```

> ℹ️ The global `AriaEmbed` object is available when using the CDN. Make sure to include the script **before** you call `init()` or `render()`.

---

## 🧭 Overview

This widget library provides two main features:

1. **Invoice Validation**: Used in Aria's invoice validation workflow when validation is delegated to Aria instead of being managed directly by the partner. It helps capture debtor confirmation directly via a secure modal embedded in your frontend.

2. **Payment Method Setup**: Allows debtors to configure their payment methods (such as SEPA Direct Debit mandates) through a secure, user-friendly interface.

---

## ✨ Features

- ✅ Secure iframe-based validation and payment setup
- 🎨 Fully customizable via CSS variables
- 🌍 Supports multiple languages: English, French
- ♿ Accessible and screen-reader friendly
- 🔐 Origin checking and sandboxing
- 🔁 Simple lifecycle with `.render()` and `.destroy()`
- 📦 Lightweight and framework-agnostic

---

## 🔧 Quick Start

### 1. Initialize the library

```ts
import AriaEmbed from '@hello-aria/embed'

// Sandbox environment (testing)
AriaEmbed.init({
    environment: 'sandbox',
    language: 'EN',
    styles: {
        '--color-primary': '#3b82f6'
    }
})

// Production environment (live traffic)
AriaEmbed.init({
    environment: 'production',
    language: 'EN',
    styles: {
        '--color-primary': '#3b82f6'
    }
})
```

### 2. Render the widgets

#### Invoice Validation Widget

```ts
AriaEmbed.invoiceValidation.render({
    contact: {
        email: 'debtor@email.com',
        firstName: 'Alice',
        lastName: 'Martin'
    },
    invoiceId: 'inv_12345',
    onSuccess: (payload) => console.log('Validated:', payload),
    onError: (error) => console.error('Validation error:', error)
})
```

#### Payment Method Widget

```ts
AriaEmbed.payment.render({
    debtor: {
        debtorId: 'debtor_123',
        debtorIdentifier: {
            country: 'FR',
            type: 'siren',
            value: '123456789'
        },
        debtorEmail: 'debtor@email.com'
    },
    paymentMethod: {
        type: 'SEPA_DIRECT_DEBIT',
        sepaDebitType: 'CORE'
    },
    onSuccess: (payload) => console.log('Payment method configured:', payload),
    onError: (error) => console.error('Payment error:', error)
})
```

---

## 🧩 API

### `init(options: InitOptions): AriaEmbedAPI`

Initializes the widget with your environment, language, and optional theme styles.

| Option        | Type                        | Required | Description                                                                                 |
| ------------- | --------------------------- | -------- | ------------------------------------------------------------------------------------------- |
| `environment` | `'production' \| 'sandbox'` | ✅       | Which Aria environment to target. Use `sandbox` for testing, `production` for live traffic. |
| `language`    | `'FR' \| 'EN'`              | ✅       | Supported UI languages                                                                      |
| `styles`      | object                      | ❌       | Custom CSS variables for theming                                                            |

---

### Invoice Validation Feature

#### `invoiceValidation.render(options: InvoiceValidationRenderOptions): void`

Renders the modal with the validation iframe.

| Option      | Type                     | Required | Description                          |
| ----------- | ------------------------ | -------- | ------------------------------------ |
| `contact`   | `{ email: string; ... }` | ✅       | Debtor contact info                  |
| `invoiceId` | string                   | ✅       | ID of the invoice to validate        |
| `onSuccess` | `(payload) => void`      | ❌       | Called when validation is successful |
| `onError`   | `(error) => void`        | ❌       | Called when an error occurs          |

#### `invoiceValidation.destroy(): void`

Destroys the widget and removes all resources.

#### `invoiceValidation.isRendered(): boolean`

Checks if the modal is currently open.

---

### Payment Feature

#### `payment.render(options: PaymentRenderOptions): void`

Renders the modal for payment method configuration.

| Option                        | Type                                               | Required | Description                                                 |
| ----------------------------- | -------------------------------------------------- | -------- | ----------------------------------------------------------- |
| `debtor`                      | object                                             | ✅       | Debtor information                                          |
| `debtor.debtorId`             | string                                             | ✅       | Unique identifier for the debtor                            |
| `debtor.debtorIdentifier`     | `{ country: string; type: string; value: string }` | ✅       | Debtor's business identifier (e.g., siren, siret)           |
| `debtor.debtorEmail`          | string                                             | ✅       | Valid email address for the debtor                          |
| `paymentMethod`               | object                                             | ✅       | Payment method configuration                                |
| `paymentMethod.type`          | string                                             | ✅       | Payment method type (currently `'SEPA_DIRECT_DEBIT'`)       |
| `paymentMethod.sepaDebitType` | `'CORE'`                                           | ✅\*     | SEPA debit type (\*required when type is SEPA_DIRECT_DEBIT) |
| `onSuccess`                   | `(payload) => void`                                | ❌       | Called when payment method is successfully configured       |
| `onError`                     | `(error) => void`                                  | ❌       | Called when an error occurs                                 |

**SEPA Debit Types:**

- `CORE` — Standard SEPA Direct Debit for consumers and businesses

#### `payment.destroy(): void`

Destroys the widget and removes all resources.

#### `payment.isRendered(): boolean`

Checks if the modal is currently open.

---

### Global Methods

#### `reinit(options: InitOptions): AriaEmbedAPI`

Reinitializes the widget with new options.

#### `destroy(): void`

Completely resets the widget and removes all styles and listeners for both features.

---

## 🎨 Theming

You can customize the look and feel of the widget using CSS variables passed in `styles`:

```ts
{
  '--color-primary': '#3b82f6',
  '--fonts-serif': '"Georgia", serif'
}
```

### Available Variables

- `--color-primary`
- `--color-buttonTextPrimary`
- `--fonts-noserif`
- `--fonts-serif`

---

## 🛡 Security & Accessibility

- ✅ Origin checking (messages only accepted from your environment's domain)
- ✅ Sandboxed iframe
- ✅ Tab trapping and ESC-to-close
- ✅ Screen reader-friendly `aria-*` attributes
- ✅ Timeout handling for stale widgets

---

## 📖 Business Context

### Invoice Validation

This widget is part of Aria's **invoice validation** workflow.

Invoices validated via this modal:

- Are linked to a **Debtor contact** (email is mandatory)
- Can be used to unblock payouts or repayments
- Are validated directly by the Debtor in a secure, user-friendly flow

Validation is required when the invoice is associated with an advance or receivable.

### Payment Method Setup

This widget enables debtors to configure their payment methods for loan repayments.

Payment methods configured via this modal:

- Are linked to a specific **Debtor** (identified by debtorId and business identifier)
- Support SEPA Direct Debit mandates (CORE)
- Require electronic signature for mandate acceptance
- Enable automated payment collection for loan repayments

Payment method setup is typically required before a debtor can receive funds or begin repayment schedules.

---

## 🧪 Error Handling

The library provides two custom error classes:

- `InitializationError` — thrown during `init()` if required options are missing or malformed.
- `RenderError` — thrown during `render()` if the widget fails to mount or receives invalid options.

---

## 🌍 Supported Languages

- `EN` (English)
- `FR` (French)

---

## 🧼 Cleanup and Lifecycle

- Automatically restores body scroll after destroy
- Adds and removes `aria-live` announcements
- Prevents double rendering
- Handles iframe load timeout

---

## 📜 License

MIT

---

## 🙋 Need Help?

For support and onboarding, please contact your Aria Implementation Manager.