Skip to main content

Payin Webhooks

Payin webhooks notify the merchant when the acquiring order status changes. The main merchant-facing event is:

acquiring.order.updated

When creating a Payin order, pass notify_webhook_id. The webhook must be active and subscribed to acquiring.order.updated, acquiring.payment.updated, or acquiring.*.

When It Is Sent

acquiring.order.updated is sent when the order reaches a state the merchant should handle, for example:

  1. The user paid enough and the order becomes completed.
  2. The user paid only part of the amount and the order becomes partial_paid.
  3. The order expired with no confirmed payment and becomes expired.
  4. The order expired with some confirmed amount but not enough and becomes underpaid.
  5. A payment is detected after expiry and anomaly_tag=expired_paid.

Payload Example

{
"event_id": "acqevt_acq_order_xxx",
"event_type": "acquiring.order.updated",
"business_type": "acquiring",
"business_id": "acq_order_xxx",
"occurred_at": 1781789497,
"version": "v1",
"data": {
"provider_event": "transaction_confirmed",
"anomaly_tag": "",
"order_id": "acq_order_xxx",
"platform_order_no": "P202606190001",
"out_trade_no": "payin_202606190001",
"previous_status": "pending",
"status": "completed",
"status_changed": true,
"amount_changed": true,
"order_currency": "USD",
"pay_amount": "20.00",
"paid_amount_total": "20.00",
"remaining_amount": "0",
"overpaid_amount": "0",
"underpay_tolerance": "0",
"expire_time": 1781789497,
"updated_at": 1781789497
}
}

Important Fields

FieldDescription
event_idWebhook event ID for idempotency.
event_typeacquiring.order.updated.
business_idSame as order_id.
data.order_idBeyounger acquiring order ID.
data.out_trade_noMerchant order number.
data.previous_statusPrevious order status.
data.statusLatest order status.
data.pay_amountExpected amount.
data.paid_amount_totalConfirmed paid amount.
data.remaining_amountRemaining amount.
data.overpaid_amountOverpaid amount.
data.underpay_toleranceUnderpayment tolerance.
data.anomaly_tagException marker.

Crypto Payin Status

Crypto Payin order status is aggregated from payment records under the order. Do not treat it as a simple success/failure flow.

data.statusFinal?MeaningMerchant action
partial_paidNoSome amount has been confirmed, but not enough.Do not mark as paid. Wait for more payment or request top-up.
completedYesConfirmed amount plus tolerance satisfies the expected amount.Mark the merchant order as paid.
underpaidYesThe order expired with confirmed amount, but still below tolerance.Mark as exception and handle top-up, refund, or manual review.
expiredYesThe order expired with no confirmed paid amount.Mark as expired.

Notes:

  1. paid_amount_total is confirmed paid amount.
  2. Unconfirmed on-chain transactions should not be treated as success.
  3. overpaid_amount > 0 means the user overpaid.
  4. anomaly_tag=expired_paid means payment was detected after expiry.
  5. One order may have multiple payment records. Use the aggregated data.status as the order-level result.

Merchant Handling

  1. Verify the signature before business processing.
  2. Use event_id for idempotency.
  3. Find the merchant order by data.order_id or data.out_trade_no.
  4. Only data.status=completed should mark the merchant order as paid.
  5. Build exception handling for partial_paid, underpaid, and expired_paid.
  6. Query GET /payment/acquiring/orders/{order_id} for fallback confirmation.