QR Payment Order Status
Emitted when a QR payment reaches a terminal state.
Event Types
| Event | When Emitted |
|---|---|
qrpay.order.completed | QR payment successful; upstream funds released to the acquiring merchant |
qrpay.order.failed | QR payment unsuccessful; the full debit returned to the available balance |
qrpay.order.refunded | QR payment refunded; funds returned to the member’s available balance |
Delivery Contract
- We send a
POSTrequest withapplication/jsonto your configured endpoint, with a 10-second timeout. - Any 2xx response acknowledges receipt. Non-2xx responses and timeouts trigger retries with backoff.
- Four request headers:
content-type·z-signature·z-event-id·z-event-type。 - Deduplicate by
z-event-id— the same event may be delivered more than once.
There are no amounts, asset codes, card number fragments or risk-control reasons. This is a security boundary: the webhook endpoint is your service, whose transport and storage we cannot guarantee.
The GET /v1/<resource>/{id} endpoint applies API key, scope and on-behalf-of checks. Fetch details using data.id;
do not use webhook payloads as the source of amounts for your ledger.
Event Details
qrpay.order.completed
QR payment successful; upstream funds released to the acquiring merchantEmitted when the upstream confirms payment completion. This is a terminal state.
{
"event_id": "evt_bd15c8073e4a49f2861b09df7ac35e10",
"event_type": "qrpay.order.completed",
"created_at": "2026-08-12T15:07:52Z",
"merchant_id": "acme",
"livemode": true,
"data": {
"object": "qrpay_order",
"id": "6d3f9b21-8c07-4a5e-91d4-27e0b6a3fc58",
"external_member_id": "u_88123",
"status": "completed",
"status_version": 4
}
}qrpay.order.failed
QR payment unsuccessful; the full debit returned to the available balanceUpstream rejection, unavailable corridors, and expired quotes can all lead here: failure is not an exceptional path. Without this event, polling is your only way to know, and polling requires knowing that an order exists. Otherwise you would wait for a completed event that never arrives.
{
"event_id": "evt_af02e71d94b6435c8071cd23e6b95f4a",
"event_type": "qrpay.order.failed",
"created_at": "2026-08-12T15:09:03Z",
"merchant_id": "acme",
"livemode": true,
"data": {
"object": "qrpay_order",
"id": "6d3f9b21-8c07-4a5e-91d4-27e0b6a3fc58",
"external_member_id": "u_88123",
"status": "failed",
"status_version": 3
}
}qrpay.order.refunded
QR payment refunded; funds returned to the member’s available balanceEmitted after the acquiring-side refund arrives. It directly affects the member balance, so it is separate from failed. They have different accounting meanings: one payment never succeeded; the other succeeded and was subsequently refunded.
{
"event_id": "evt_5c8b0a2f61d7452e93af6b04d18e37c9",
"event_type": "qrpay.order.refunded",
"created_at": "2026-08-13T10:21:35Z",
"merchant_id": "acme",
"livemode": true,
"data": {
"object": "qrpay_order",
"id": "6d3f9b21-8c07-4a5e-91d4-27e0b6a3fc58",
"external_member_id": "u_88123",
"status": "refunded",
"status_version": 6
}
}Signature Verification
The signature verification procedure is the same for all events. See Webhook Overview; use the Signature Debugger to compare signing strings character by character.