> ## Documentation Index
> Fetch the complete documentation index at: https://walletconnect-pay-docs-wcagent-nest-api-reference-under-pay.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook event reference

> Field-level reference for the payment webhook payload: the envelope, the payment snapshot, and each stage object.

This page is the field-level reference for the payment webhook payload, `api_version` `2026-05-18`. It documents every field, its type and nullability, and which stage objects are populated for each event type. For endpoint setup, signature verification, and delivery guarantees, see [Webhooks](/payments/webhooks).

<Warning>
  **The contract is additive-only.** Within this `api_version`, fields are never removed or renamed, and types and nullability never change. New **optional** fields and new values for extensible strings (such as `fee.kind`) can be added at any time. Ignore fields you don't recognize, and never validate payloads with a schema that rejects unknown fields; strict validation will break your integration.
</Warning>

All timestamps in the payload are ISO 8601 UTC strings.

## The event envelope

Every event has the same top-level shape.

| Field | Type | Description |
| - | - | - |
| `id` | string | Unique event identifier, prefixed `evt_`. The deduplication key: delivery is at-least-once, so the same `id` can arrive more than once. Do not deduplicate by `payment_id`; one payment emits multiple events. |
| `type` | string | The event type. One of the seven `payment.*` event types; see [the matrix below](#stage-objects-by-event-type). |
| `api_version` | string | The payload contract version, `2026-05-18`. Changes within a version are additive-only. |
| `created_at` | string | When the event occurred, not when it was delivered. |
| `data` | object | The [payment snapshot](#the-payment-snapshot-data) at event time. |

## The payment snapshot (`data`)

`data` is always a **full snapshot of the payment at the moment the event occurred**, never a delta. Every event type carries the same field set; what varies is `status` and which stage objects are non-null.

| Field | Type | Description |
| - | - | - |
| `payment_id` | string | Payment identifier, the same id used across the Merchant API. |
| `merchant_id` | string | Merchant identifier, the same external merchant id used across the Merchant API. |
| `live` | boolean | Whether this is a live payment. Test-mode payments carry `false` and are only delivered to test-mode endpoints. Verify `live` is `true` before driving real fulfillment. |
| `payment_state_version` | integer | Monotonic per-payment version, starting at `0` on the first event. The ordering guard: ignore any event whose version is lower than or equal to one already processed for the same `payment_id`. See [Out-of-order delivery](/payments/webhooks#out-of-order-delivery). |
| `reference_id` | string | The merchant-provided order reference attached at payment creation. Primary reconciliation key against your own records. Not unique: a new payment for the same order (for example a checkout retry) carries the same reference. |
| `status` | string | Payment status at event time: `requires_action`, `processing`, `succeeded`, `failed`, `expired`, or `cancelled`. There is no `settled` status; settlement is a stage of a succeeded payment. |
| `amount` | [Amount](#amount) | The requested payment amount. |
| `created_at` | string | When the payment was created. |
| `expires_at` | string | When the payment stops accepting buyer action. |
| `processing` | [Processing](#processing) \| null | Populated once the buyer has committed to a payment option. |
| `success` | [Success](#success) \| null | Populated once the payment succeeded. |
| `failed` | [Failed](#failed) \| null | Populated once the payment failed. |
| `cancelled` | [Cancelled](#cancelled) \| null | Populated once the payment was cancelled. |
| `expired` | [Expired](#expired) \| null | Populated once the payment expired. |
| `settled` | [Settled](#settled) \| null | Populated once merchant settlement completed. |

### Stage objects by event type

Which stage objects are non-null depends on the event type. Each event type's page carries a full example, taken verbatim from the golden fixtures the payload contract is tested against.

| Event type | `status` | `processing` | `success` | `failed` | `cancelled` | `expired` | `settled` |
| - | - | - | - | - | - | - | - |
| [payment.created](/payments/webhook-events/payment-created) | `requires_action` | null | null | null | null | null | null |
| [payment.processing](/payments/webhook-events/payment-processing) | `processing` | present | null | null | null | null | null |
| [payment.succeeded](/payments/webhook-events/payment-succeeded) | `succeeded` | present | present | null | null | null | usually null |
| [payment.failed](/payments/webhook-events/payment-failed) | `failed` | may be present | null | present | null | null | null |
| [payment.expired](/payments/webhook-events/payment-expired) | `expired` | may be present | null | null | null | present | null |
| [payment.cancelled](/payments/webhook-events/payment-cancelled) | `cancelled` | null | null | null | present | null | null |
| [payment.settled](/payments/webhook-events/payment-settled) | `succeeded` | present | present | null | null | null | present |

"May be present" means the payment can fail or expire either before or after processing started: `processing` is `null` when the buyer never committed to a payment option, and populated otherwise. Cancellation is only possible while the payment awaits buyer action, so `payment.cancelled` always carries `processing: null`. On `payment.succeeded`, `settled` is `null` unless settlement had already completed at snapshot time; settlement completion is carried by `payment.settled`.

## Objects

### Amount

An asset amount. Used for `data.amount` and inside the [Processing](#processing), [Fee](#fee), and [Settled](#settled) objects.

| Field | Type | Description |
| - | - | - |
| `unit` | string | The asset: `iso4217/XXX` for fiat currencies (for example `iso4217/USD`) or `caip19/...` for on-chain assets. |
| `value` | string | Integer string in the smallest unit of the asset: minor units for fiat, raw base units for tokens. Token decimals are not included in the payload. |

### Fee

Fee applied to the payment, inside [Processing](#processing).

| Field | Type | Description |
| - | - | - |
| `kind` | string | Extensible string. The only value at launch is `base_plus_percent`. Do not switch exhaustively on it; new kinds can be added within this `api_version`. Whatever the kind, `total_amount` is always present. |
| `base_amount` | [Amount](#amount) | The fixed component of the fee. |
| `percent` | object | The percentage as an exact rational: `numerator` and `denominator`, both integer strings. For example `29/1000` is 2.9%. |
| `percent_amount` | [Amount](#amount) | The percentage component of the fee. |
| `total_amount` | [Amount](#amount) | The total fee charged. `base_amount` and `percent_amount` break it down. |

### Processing

Present once the buyer has committed to a payment option.

| Field | Type | Description |
| - | - | - |
| `processing_at` | string | When the buyer committed to the payment option. |
| `option_amount` | [Amount](#amount) | What the buyer pays gross, in the asset of the payment option they selected. |
| `fee` | [Fee](#fee) \| null | Fee applied to this payment, or `null` when no fee is configured. |
| `settlement_amount` | [Amount](#amount) | What the merchant is expected to receive, net of `fee`. |
| `buyer_caip10` | string \| null | The buyer's on-chain account ([CAIP-10](https://chainagnostic.org/CAIPs/caip-10)), or `null` when the payment has no on-chain buyer (for example, payments settled inside an exchange). |
| `chain_caip2` | string | The chain the payment executes on ([CAIP-2](https://chainagnostic.org/CAIPs/caip-2)). Needed to interpret transaction ids. |

### Success

Present once the payment succeeded.

| Field | Type | Description |
| - | - | - |
| `succeeded_at` | string | When the payment succeeded. |
| `tx_id` | string \| null | On-chain transaction id, or `null` when there is no on-chain transaction. Format is chain-specific; interpret with `processing.chain_caip2`. |

### Failed

Present once the payment failed.

| Field | Type | Description |
| - | - | - |
| `failed_at` | string | When the payment failed. |
| `failure_reason` | string \| null | Human-readable diagnostic, or `null`. Not machine-parseable: values may change without notice. Display it if useful, but never branch on it. |

### Cancelled

Present once the payment was cancelled.

| Field | Type | Description |
| - | - | - |
| `cancelled_at` | string | When the payment was cancelled. |
| `cancellation_reason` | string \| null | Human-readable diagnostic, or `null`. Not machine-parseable: values may change without notice. Display it if useful, but never branch on it. |

### Expired

Present once the payment expired.

| Field | Type | Description |
| - | - | - |
| `expired_at` | string | When the payment expired. |

### Settled

Present once merchant settlement completed.

| Field | Type | Description |
| - | - | - |
| `settled_at` | string | When settlement completed. |
| `tx_id` | string \| null | Settlement transaction id, or `null` when there is no on-chain settlement transaction. Format is chain-specific; interpret with `processing.chain_caip2`. |
| `amount` | [Amount](#amount) | What actually settled to the merchant, as opposed to `processing.settlement_amount`, which is the expected net amount at processing time. |

## Next steps

<CardGroup cols={2}>
  <Card title="Webhooks" icon="webhook" href="/payments/webhooks">
    Endpoint setup, signature verification, and delivery guarantees.
  </Card>

  <Card title="Test mode" icon="flask" href="/payments/test-mode">
    Drive a test payment through every transition and watch these events arrive.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.