Receive payment.updated
The draft payment.updated event tells a merchant that a payment state changed.
The event is a notification: verify its signature, deduplicate it, validate the
payload, and apply the transition idempotently.
Verify. Deduplicate. Validate. Apply. Acknowledge.
Documentation-only endpoint
.invalid URL is reserved and cannot receive a webhook. The signing value
is public documentation data, not a credential.
Event shape
Signature headers
Build the canonical string by joining the version, event identifier, timestamp,
and base64url SHA-256 digest of the raw body with line-feed characters:
The reproducible vector below hashes the UTF-8 bytes returned by
JSON.stringify(event) for the event above, with no trailing newline. A real
receiver must instead hash the exact bytes it received and must not parse and
reserialize the body before verification.
Processing order
1
Capture the raw body
Preserve the exact bytes received. Parsing and reserializing JSON before
verification changes the digest.
2
Verify authenticity
Check the version, key identifier, timestamp, event identifier, and
signature. Compare the computed signature in constant time.
3
Reserve the event identifier
Insert
event_id into a unique store before applying business effects. If
it already exists, return the same successful acknowledgement without
repeating fulfilment.4
Validate and apply
Match
payment_id, external_reference, amounts, asset, network, and
destination to the local order. Apply only a valid lifecycle transition.5
Acknowledge
Return an empty
200 response only after the event is safely recorded.The final retry schedule, timeout, and delivery retention policy remain
undecided. Build idempotent handling, but do not treat a particular retry
count as a launch guarantee.