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.
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.
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. |
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 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. |
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 | The requested payment amount. |
created_at | string | When the payment was created. |
expires_at | string | When the payment stops accepting buyer action. |
processing | Processing | null | Populated once the buyer has committed to a payment option. |
success | Success | null | Populated once the payment succeeded. |
failed | Failed | null | Populated once the payment failed. |
cancelled | Cancelled | null | Populated once the payment was cancelled. |
expired | Expired | null | Populated once the payment expired. |
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 | requires_action | null | null | null | null | null | null |
| payment.processing | processing | present | null | null | null | null | null |
| payment.succeeded | succeeded | present | present | null | null | null | usually null |
| payment.failed | failed | may be present | null | present | null | null | null |
| payment.expired | expired | may be present | null | null | null | present | null |
| payment.cancelled | cancelled | null | null | null | present | null | null |
| 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, Fee, and 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.
| 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 | 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 | The percentage component of the fee. |
total_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 | What the buyer pays gross, in the asset of the payment option they selected. |
fee | Fee | null | Fee applied to this payment, or null when no fee is configured. |
settlement_amount | Amount | What the merchant is expected to receive, net of fee. |
buyer_caip10 | string | null | The buyer's on-chain account (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). 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 | What actually settled to the merchant, as opposed to processing.settlement_amount, which is the expected net amount at processing time. |