# Webhook Details (/en/webhooks/webhook-details)



Multiple webhook endpoints [#multiple-webhook-endpoints]

An organization can configure multiple webhook endpoints. Every enabled endpoint receives its own delivery record and is retried independently: a `2xx` response marks only that endpoint delivered, while `429`, `5xx`, and network failures retry only the failing endpoint. Every endpoint has its own signing secret for `X-Yolfi-Signature`; the secret is returned only when the endpoint is created or rotated.

Each endpoint has a name, URL, enabled flag, and payload adapter. Use `NONE` for the native payload documented below. Provider adapters such as `STRIPE` are intended for compatible third-party consumers. Delivery is at-least-once, so consumers must deduplicate using the signed payload `id`. `X-Yolfi-Event-ID` mirrors that value for convenience, but it is not signed separately.

Optional `metadataFilters` are generic exact-match filters evaluated only against the current event's `data.metadata` string values. They do not inherit metadata from a subscription and must not be used as authorization or tenant routing.

Talivia revenue analytics uses a native endpoint with adapter `NONE`:

```text
https://talivia.com/api/payments/yolfi/YOUR_WEBSITE_ID/webhook
```

Connect Yolfi from Talivia to configure this endpoint automatically; do not create it manually. An organization can have one Talivia analytics endpoint. The endpoint URL identifies your Talivia website, so no website identifier is needed in payment metadata or `metadataFilters`. The organization API key is used to manage the endpoint and is never used to verify webhook deliveries.

Webhook Event Types [#webhook-event-types]

Each webhook event contains a standardized payload with information about what happened. This guide provides detailed information about each event type.

***

Common Payload Structure [#common-payload-structure]

All webhook events follow the same structure:

```json
{
  "id": "evt_abc123",
  "type": "invoice.created",
  "created": 1699900000,
  "livemode": true,
  "data": { ... }
}
```

| Field      | Type    | Description                                     |
| :--------- | :------ | :---------------------------------------------- |
| `id`       | string  | Unique event identifier (format: `evt_` + UUID) |
| `type`     | string  | Event type (e.g., `"invoice.created"`)          |
| `created`  | integer | Unix timestamp when the event was created       |
| `livemode` | boolean | `true` in production, `false` in sandbox        |
| `data`     | object  | The affected object (invoice data directly)     |

***

Invoice Events [#invoice-events]

Invoice and payment events from standalone [API Checkout](/en/checkout) contain
`checkoutSessionId` and may contain `merchantOrderId`, but do not contain `paylinkId`. Paylink and
subscription flows continue to include `paylinkId`.

Invoice Created [#invoice-created]

Triggered when payment is initiated (user clicks pay button).

```json
{
  "id": "evt_abc123",
  "type": "invoice.created",
  "created": 1699900000,
  "livemode": true,
  "data": {
    "paylinkId": "120e3400-e12b-04d4-a716-446417440031",
    "invoiceId": "550e8400-e29b-41d4-a716-446655440000",
    "checkoutSessionId": "ycs_0123456789abcdef0123456789abcdef",
    "subscriptionId": "550e8400-e29b-41d4-a716-446655440010",
    "orgId": "org_def456",
    "chainId": 42161,
    "token": "0xaf88...5831",
    "symbol": "USDC",
    "network": "ARB",
    "paymentType": "RECURRING",
    "amount": "1.00",
    "amountUsd": "1.00",
    "currency": "USD",
    "rate": "1.00",
    "status": "pending",
    "expiresAt": "2024-11-15T14:00:00.000Z",
    "createdAt": "2024-11-14T14:00:00.000Z",
    "updatedAt": "2024-11-14T14:00:00.000Z",
    "metadata": { "renewal_campaign": "summer" },
    "customer": {
      "email": "customer@example.com",
      "clientReferenceId": "cust_123",
      "name": "John Doe"
    }
  }
}
```

Invoice Overdue [#invoice-overdue]

Triggered when payment deadline passes without payment.

This event is scoped to a single invoice/payment attempt. It does not mean an existing recurring subscription should be cancelled or access should be revoked. For subscription access changes, handle `subscription.overdue` and `subscription.cancelled`.

```json
{
  "id": "evt_abc123",
  "object": "event",
  "type": "invoice.overdue",
  "created": 1699900000,
  "livemode": true,
  "data": {
    "paylinkId": "120e3400-e12b-04d4-a716-446417440031",
    "invoiceId": "550e8400-e29b-41d4-a716-446655440000",
    "checkoutSessionId": "ycs_0123456789abcdef0123456789abcdef",
    "subscriptionId": "550e8400-e29b-41d4-a716-446655440010",
    "orgId": "org_def456",
    "chainId": 42161,
    "token": "0xaf88...5831",
    "symbol": "USDC",
    "network": "ARB",
    "paymentType": "RECURRING",
    "amount": "1.00",
    "amountUsd": "1.00",
    "currency": "USD",
    "rate": "1.00",
    "status": "expired",
    "expiresAt": "2024-11-15T14:00:00.000Z",
    "createdAt": "2024-11-14T14:00:00.000Z",
    "updatedAt": "2024-11-15T14:01:00.000Z",
    "metadata": { "renewal_campaign": "summer" },
    "customer": {
      "email": "customer@example.com",
      "clientReferenceId": "cust_123",
      "name": "John Doe"
    }
  }
}
```

Subscription Cancelled [#subscription-cancelled]

Triggered when a subscription is cancelled.

```json
{
  "id": "evt_abc123",
  "object": "event",
  "type": "subscription.cancelled",
  "created": 1699900000,
  "livemode": true,
  "data": {
    "subscriptionId": "sub_abc123",
    "status": "cancelled",
    "expiresAt": "2024-11-15T14:00:00.000Z",
    "recurringInterval": "MONTH",
    "productName": "Premium Plan",
    "orgId": "org_def456",
    "organizationName": "Example Store",
    "customerId": "cust_123",
    "paylinkId": "120e3400-e12b-04d4-a716-446417440031",
    "invoiceId": "550e8400-e29b-41d4-a716-446655440000",
    "chainId": 42161,
    "token": "0xaf88...5831",
    "symbol": "USDC",
    "network": "ARB",
    "paymentType": "RECURRING",
    "amount": "1.00",
    "amountUsd": "1.00",
    "currency": "USD",
    "rate": "1.00",
    "createdAt": "2024-11-14T14:00:00.000Z",
    "updatedAt": "2024-11-14T15:00:00.000Z",
    "metadata": {},
    "customer": {
      "email": "customer@example.com",
      "clientReferenceId": "cust_123",
      "name": "John Doe"
    }
  }
}
```

***

Payment Events [#payment-events]

Payment Confirmed [#payment-confirmed]

Triggered when payment has received enough blockchain confirmations to be considered final.

```json
{
  "id": "evt_abc123",
  "object": "event",
  "type": "payment.confirmed",
  "created": 1699900000,
  "livemode": true,
  "data": {
    "paylinkId": "120e3400-e12b-04d4-a716-446417440031",
    "invoiceId": "550e8400-e29b-41d4-a716-446655440000",
    "checkoutSessionId": "ycs_0123456789abcdef0123456789abcdef",
    "subscriptionId": "550e8400-e29b-41d4-a716-446655440010",
    "orgId": "org_def456",
    "chainId": 42161,
    "token": "0xaf88...5831",
    "symbol": "USDC",
    "network": "ARB",
    "paymentType": "RECURRING",
    "amount": "1.00",
    "amountUsd": "1.00",
    "currency": "USD",
    "rate": "1.00",
    "status": "confirmed",
    "expiresAt": "2024-11-15T14:00:00.000Z",
    "createdAt": "2024-11-14T14:00:00.000Z",
    "updatedAt": "2024-11-14T15:00:00.000Z",
    "metadata": {},
    "customer": {
      "email": "customer@example.com",
      "clientReferenceId": "cust_123",
      "name": "John Doe"
    }
  }
}
```

For an independent API Checkout Session, the correlation fields look like this:

```json
{
  "type": "payment.confirmed",
  "data": {
    "invoiceId": "550e8400-e29b-41d4-a716-446655440000",
    "checkoutSessionId": "ycs_0123456789abcdef0123456789abcdef",
    "merchantOrderId": "order-1042",
    "paymentType": "ONE_TIME",
    "status": "confirmed"
  }
}
```

The omission of `paylinkId` is intentional: no Paylink exists for this payment.

***

Subscription Events [#subscription-events]

Subscription Overdue [#subscription-overdue]

Triggered when a subscription expires without payment renewal.

This event is subscription-scoped. Use it when your app should mark an existing subscription as past due or inactive according to your access policy.

A fully paid invoice still awaiting confirmation can defer this event for up to one hour after the subscription period ends. Once the subscription becomes overdue, a later `payment.confirmed` event records the payment but does not automatically reactivate the subscription or extend its expiration. Access then requires manual resolution.

```json
{
  "id": "evt_abc123",
  "type": "subscription.overdue",
  "created": 1699900000,
  "livemode": true,
  "data": {
    "subscriptionId": "550e8400-e29b-41d4-a716-446655440000",
    "status": "overdue",
    "expiresAt": "2024-11-15T14:00:00.000Z",
    "recurringInterval": "MONTH",
    "productName": "Premium Plan",
    "orgId": "org_def456",
    "organizationName": "Acme Corp",
    "customerId": "550e8400-e29b-41d4-a716-446655440099",
    "paylinkId": "120e3400-e12b-04d4-a716-446417440031",
    "invoiceId": "550e8400-e29b-41d4-a716-446655440001",
    "chainId": 42161,
    "token": "0xaf88...5831",
    "symbol": "USDC",
    "network": "ARB",
    "paymentType": "RECURRING",
    "amount": "1.00",
    "amountUsd": "1.00",
    "createdAt": "2024-11-01T14:00:00.000Z",
    "updatedAt": "2024-11-15T14:01:00.000Z",
    "metadata": {},
    "customer": {
      "email": "customer@example.com",
      "name": "John Doe"
    }
  }
}
```

***

Handling Recurring Customers [#handling-recurring-customers]

When you receive `invoice.created` for a recurring customer:

**Important:** Use `clientReferenceId` or `email` to identify existing customers:

* If `clientReferenceId` or `email` already exists in your database → update existing customer (don't create new)
* If new → create new customer

The same customer may have multiple invoices over time - always use `clientReferenceId` or `email` to identify them.

To set `clientReferenceId`, pass it as a [checkout URL parameter](/en/paylinks/checkout-parameters)
when sharing a Paylink, or set it on an authenticated [API Checkout Session](/en/checkout).

***

Object Field Reference [#object-field-reference]

Invoice Object [#invoice-object]

| Field               | Type    | Description                                                              |
| :------------------ | :------ | :----------------------------------------------------------------------- |
| `paylinkId`         | string  | Paylink identifier, omitted for standalone API Checkout                  |
| `invoiceId`         | string  | Invoice identifier (UUID)                                                |
| `checkoutSessionId` | string  | Hosted Checkout Session identifier, when present                         |
| `merchantOrderId`   | string  | Merchant order identifier from API Checkout, when present                |
| `subscriptionId`    | string  | Recurring subscription identifier, when present                          |
| `orgId`             | string  | Organization ID                                                          |
| `chainId`           | integer | Blockchain chain ID                                                      |
| `token`             | string  | Token contract address                                                   |
| `symbol`            | string  | Token symbol (e.g., "USDC")                                              |
| `network`           | string  | Network name (e.g., "ARB")                                               |
| `paymentType`       | string  | `"ONE_TIME"` or `"RECURRING"`                                            |
| `amount`            | string  | Final merchant receivable in the payment token, formatted (e.g., "1.00") |
| `amountUsd`         | string  | USD equivalent of the final merchant receivable (e.g., "1.00")           |
| `currency`          | string  | Original paylink/source currency (e.g., "USD", "EUR", "CNY")             |
| `rate`              | string  | FX quote used for pricing: one payment token in the source currency      |
| `status`            | string  | Current invoice status                                                   |
| `expiresAt`         | string  | Expiration timestamp (ISO 8601)                                          |
| `createdAt`         | string  | Creation timestamp (ISO 8601)                                            |
| `updatedAt`         | string  | Last update timestamp (ISO 8601)                                         |
| `customerId`        | string  | Customer identifier (UUID, optional)                                     |
| `metadata`          | object  | Custom metadata                                                          |
| `customer`          | object  | Customer information                                                     |

Payment Object [#payment-object]

| Field               | Type          | Description                                                              |
| :------------------ | :------------ | :----------------------------------------------------------------------- |
| `paylinkId`         | string        | Paylink identifier, omitted for standalone API Checkout                  |
| `invoiceId`         | string        | Associated invoice ID                                                    |
| `checkoutSessionId` | string        | Hosted Checkout Session identifier, when present                         |
| `merchantOrderId`   | string        | Merchant order identifier from API Checkout, when present                |
| `subscriptionId`    | string        | Recurring subscription identifier, when present                          |
| `orgId`             | string        | Organization ID                                                          |
| `chainId`           | integer       | Blockchain chain ID                                                      |
| `token`             | string        | Token contract address                                                   |
| `symbol`            | string        | Token symbol (e.g., "USDC")                                              |
| `network`           | string        | Network name (e.g., "ARB")                                               |
| `paymentType`       | string        | `"ONE_TIME"` or `"RECURRING"`                                            |
| `amount`            | string        | Final merchant receivable in the payment token, formatted (e.g., "1.00") |
| `amountUsd`         | string        | USD equivalent of the final merchant receivable (e.g., "1.00")           |
| `currency`          | string        | Original paylink/source currency (e.g., "USD", "EUR", "CNY")             |
| `rate`              | string        | FX quote used for pricing: one payment token in the source currency      |
| `status`            | `"confirmed"` | Payment status                                                           |
| `expiresAt`         | string        | Expiration timestamp                                                     |
| `createdAt`         | string        | Creation timestamp                                                       |
| `updatedAt`         | string        | Last update timestamp                                                    |
| `customerId`        | string        | Customer identifier (UUID, optional)                                     |
| `metadata`          | object        | Custom metadata                                                          |
| `customer`          | object        | Customer information                                                     |

Customer Object [#customer-object]

| Field               | Type   | Description                        |
| :------------------ | :----- | :--------------------------------- |
| `email`             | string | Customer email address             |
| `clientReferenceId` | string | Your internal customer reference   |
| `name`              | string | Customer name (if provided)        |
| `phone`             | string | Customer phone (if provided)       |
| `dateOfBirth`       | string | Customer dateOfBirth (if provided) |
| `address`           | string | Customer address (if provided)     |

Subscription Object [#subscription-object]

| Field               | Type    | Description                                                              |
| :------------------ | :------ | :----------------------------------------------------------------------- |
| `subscriptionId`    | string  | Subscription identifier (UUID)                                           |
| `status`            | string  | Subscription status (e.g., "overdue")                                    |
| `expiresAt`         | string  | Expiration timestamp (ISO 8601)                                          |
| `recurringInterval` | string  | Recurring interval (e.g., "MONTH")                                       |
| `productName`       | string  | Product/service name                                                     |
| `orgId`             | string  | Organization ID                                                          |
| `organizationName`  | string  | Organization name                                                        |
| `customerId`        | string  | Customer identifier                                                      |
| `paylinkId`         | string  | Paylink identifier                                                       |
| `invoiceId`         | string  | Associated invoice ID                                                    |
| `chainId`           | integer | Blockchain chain ID                                                      |
| `token`             | string  | Token contract address                                                   |
| `symbol`            | string  | Token symbol (e.g., "USDC")                                              |
| `network`           | string  | Network name (e.g., "ARB")                                               |
| `paymentType`       | string  | `"ONE_TIME"` or `"RECURRING"`                                            |
| `amount`            | string  | Final merchant receivable in the payment token, formatted (e.g., "1.00") |
| `amountUsd`         | string  | USD equivalent of the final merchant receivable (e.g., "1.00")           |
| `currency`          | string  | Original paylink/source currency (e.g., "USD", "EUR", "CNY")             |
| `rate`              | string  | FX quote used for pricing: one payment token in the source currency      |
| `createdAt`         | string  | Subscription creation timestamp                                          |
| `updatedAt`         | string  | Last update timestamp                                                    |
| `metadata`          | object  | Custom metadata                                                          |
| `customer`          | object  | Customer information                                                     |
