Notification webhooks

Event catalog

The notification event types and their payload classes.

The notification_class field selects the meaning of a notification. There are four classes. All share the payload envelope; the table below fixes how the two conditional fields are populated per class.

Notification classes

notification_classMeaningfinality_outcomehold_reason
payment_observedThe payment was observed on-chain at the observed threshold. Progress signal, not settlement.nullnull
payment_finalizedThe payment reached finality and a terminal outcome was published.paid | refunded | failednull
payment_heldThe payment is held; no funds have moved and no outcome is finalized.nullsanctions | kyt_timeout
duplicate_payment_incidentInformational: an additional finalized payment was detected for a payment_intent_id that was already settled.nullnull

finality_outcome values

Populated only on payment_finalized.

ValueMeaning
paidThe payment swept to the merchant's approved destination; protocol fee collected on-chain.
refundedThe merchant returned a reject decision with a refund destination; the payment was refunded; protocol fee collected on-chain.
failedThe payment reached a terminal failure state without settlement or merchant-directed refund. No funds moved.

hold_reason values

Populated only on payment_held.

ValueMeaning
sanctionsThe source address matched the sanctions list. Resolution requires a merchant-supplied refund destination through the KYT response channel.
kyt_timeoutThe merchant KYT endpoint did not respond within its configured window, and the merchant's timeout policy resolved to hold.

A payment_held notification is not terminal. Once the hold is resolved, a separate payment_finalized notification is delivered for the same payment_intent_id, as a distinct record.

Records produced per scenario

One record produces one notification identity per endpoint. A single payment_intent_id may produce more than one record.

ScenarioRecords delivered
Clean paymentpayment_finalized (paid)
Merchant-rejected paymentpayment_finalized (refunded)
Failed paymentpayment_finalized (failed)
Held — sanctionspayment_held (sanctions), then payment_finalized once resolved
Held — KYT timeoutpayment_held (kyt_timeout), then payment_finalized once resolved
Duplicate detected after settlementpayment_finalized (paid) and duplicate_payment_incident (null)

Duplicate-payment caveat

duplicate_payment_incident is the merchant-actionable signal for reconciling an extra on-chain payment. It is delivered as its own record, alongside the canonical payment_finalized (paid) record for the same payment_intent_id — the settlement record already carries the authoritative outcome and is not re-issued.

This notification-plane signal is distinct from the duplicate_payment value of finality_outcome you may see on the API status projection. A losing attempt can surface there as status FAILED with finality_outcome duplicate_payment — that is not a failed payment; it means the attempt lost winner selection while the intent is already PAID. See Statuses and projections.

On this page