Payout callback
The platform sends POST JSON to the order’s notify_url. No order callback is sent when notify_url is absent. A browser return_url is separate.
Callback fields
| Field | Type | Requirement | Description |
|---|---|---|---|
tenant_id | string | Required | Merchant ID. |
platform_order_no | string | Required | Platform order ID. |
tenant_order_no | string | Required | Merchant order ID. |
status | integer | Required | Result status; success is 20. |
pay_time | string | Optional | Payment confirmation time; omitted when empty, such as for failure. |
amount | string | Required | Original order amount, not the fee-deducted amount or a dedicated actual-paid field. |
total_fee | string | Required | Order fee. |
settlement_amount | string | Required | For payins, normally amount minus fee; for payouts, normally amount plus fee. |
created_at | string | Required | Order creation time. |
utr | string | Optional | Payment reference when available; omitted when empty. |
notify_remark | string | Optional | Creation remark; returned when non-empty. |
signature | string | Required | Callback signature; exclude signature, not sign, when verifying. |
refund_at | string | Optional | Refund time when supplied for reversal; include it in verification. |
refund_reason | string | Optional | Description when supplied for reversal; not a unified detailed failure-reason field. |
Dates use YYYY-MM-DD HH:mm:ss, not ISO8601. Preserve raw values when verifying the signature. Empty optional fields can be omitted. Amount meanings differ for PayIns and payouts.
Successful callback body
{
"tenant_id": "DEMO0001",
"platform_order_no": "PRT202610051700DEMO0001",
"tenant_order_no": "DEMO-PAYOUT-001",
"status": 20,
"pay_time": "2026-10-05 17:02:00",
"amount": "500.00",
"total_fee": "10.00",
"settlement_amount": "510.00",
"created_at": "2026-10-05 17:00:00",
"utr": "123456789012",
"notify_remark": "demo-payout",
"signature": "fb6ab8d2792b0249a5e19369466c7dd1"
}Callback example · cURL
Use the cURL command below to test your callback endpoint.
curl --request POST 'https://merchant.example/webhooks/payout' \
--header 'Content-Type: application/json' \
--data-raw '{
"tenant_id": "DEMO0001",
"platform_order_no": "PRT202610051700DEMO0001",
"tenant_order_no": "DEMO-PAYOUT-001",
"status": 20,
"pay_time": "2026-10-05 17:02:00",
"amount": "500.00",
"total_fee": "10.00",
"settlement_amount": "510.00",
"created_at": "2026-10-05 17:00:00",
"utr": "123456789012",
"notify_remark": "demo-payout",
"signature": "fb6ab8d2792b0249a5e19369466c7dd1"
}'Failed callback example
{
"tenant_id": "DEMO0001",
"platform_order_no": "PRT202610051700DEMO0001",
"tenant_order_no": "DEMO-PAYOUT-001",
"status": 40,
"amount": "500.00",
"total_fee": "10.00",
"settlement_amount": "510.00",
"created_at": "2026-10-05 17:00:00",
"notify_remark": "demo-payout",
"signature": "adf799e94bc2928ba3e2de63cae9fca9"
}Acknowledgment
Return HTTP 200 and the plain body success or ok. Matching is case-insensitive and trims surrounding whitespace. An HTTP 200 alone, or JSON such as {"status":200}, is insufficient. Compatible JSON acknowledgments include {"code":200,"message":"success"}, {"success":true}, {"isSucceed":true} and {"data":"OK"}. Plain text is the recommended unambiguous form.
HTTP/1.1 200 OK
Content-Type: text/plain
successDelivery & result
Callbacks are result notifications, not a guarantee of exactly-once delivery. Retries are bounded, and a success notification may be repeated for the same order. Status 20 is success; see the full status reference for corrections, expiration and reversal. If the notification fails, the payment result itself is unchanged; use status query for confirmation.