Payment callbacks
Use payment callbacks for request-level transaction state updates after a Checkout payment request has been created.
This page documents the callback payload family separately from:
GET /payments/status, which is your polling endpoint- notify events, which are lighter lifecycle messages
What a callback represents​
A payment callback is a request-level transaction snapshot.
Treat it as a durable state update for the whole payment request, not just one payer attempt.
Current frozen Sandbox evidence covers these request-level callback states:
CompletedCancelled
Additional terminal variants may be added later, but these two shapes are already frozen in the retained contract fixtures used by the docs test suite.
Contract summary​
Every callback snapshot currently includes:
idtransaction_idamountpayments_statusfeescurrencystatustimestampspayerspayeesfraud_check_status
Completed callback example​
{
"id": "opaque-payment-id-a8Q3x",
"transaction_id": "merchant-order-a8Q3x",
"amount": "25.00",
"payments_status": {
"paid": "25.00 TTD",
"remaining": "0.00 TTD",
"metadata": []
},
"fees": {
"total": "3.91",
"card_processing": "3.91",
"platform_processing": "0.00",
"agent_processing": "0.00",
"payer_pays": "0.00",
"payee_pays": "0.00",
"merchant_pays": "3.91",
"convenience": "0.00"
},
"currency": "TTD",
"status": "Completed",
"timestamps": {
"created_time": "2026-08-10 08:15:09",
"updated_time": "2026-08-11 02:42:21",
"expire_time": "2026-08-10 11:15:09"
},
"payers": [
{
"mobile_number": "+1XXXXXXXXXX",
"amount": "25.00",
"payment_channel": "payment_link",
"payment_method": "card",
"fee": "0.00",
"tip": "0.00",
"tax": "0.00",
"convenience_fee": "0.00",
"status": "Completed",
"expire_time": "2026-08-10 11:15:09",
"metadata": "",
"url": "https://sandbox.paywise.co/example-hosted-payment",
"expire_date_time": "2026-08-10 11:15:09"
}
],
"payees": [
{
"mobile_number": "+1XXXXXXXXXX",
"amount": "21.09",
"delay_days": 0,
"fees_covered": 0,
"fee": "3.91"
}
],
"fraud_check_status": "passed"
}
Cancelled callback example​
{
"id": "opaque-payment-id-cancel-wallet",
"transaction_id": "journey-wallet-cancel-20260814a",
"amount": "25.00",
"payments_status": {
"paid": "0.00 TTD",
"remaining": "25.00 TTD",
"metadata": []
},
"fees": {
"total": "0.50",
"card_processing": "0.00",
"platform_processing": "0.50",
"agent_processing": "0.00",
"payer_pays": "0.00",
"payee_pays": "0.00",
"merchant_pays": "0.50",
"convenience": "0.00"
},
"currency": "TTD",
"status": "Cancelled",
"timestamps": {
"created_time": "2026-08-14 13:18:00",
"updated_time": "2026-08-14 13:19:08",
"expire_time": "2026-08-14 16:18:00"
},
"payers": [
{
"mobile_number": "+1XXXXXXXXXX",
"amount": "25.00",
"payment_channel": "payment_link",
"payment_method": "wallet",
"fee": "0.00",
"tip": "0.00",
"tax": "0.00",
"convenience_fee": "0.00",
"status": "Cancelled",
"expire_time": "2026-08-14 16:18:00",
"metadata": "",
"url": "https://paywise.app.link/example-wallet-payment",
"expire_date_time": "2026-08-14 16:18:00"
}
],
"payees": [
{
"mobile_number": "+1XXXXXXXXXX",
"amount": "24.50",
"delay_days": 0,
"fees_covered": 0,
"fee": "0.50"
}
],
"fraud_check_status": "passed"
}
How to use callbacks safely​
- Treat delivery as at-least-once
- Make your receiver idempotent
- Do not assume event order from network arrival time alone
- Persist
transaction_id,id,status, and your receive timestamp - Use
GET /payments/statuswhen you need the latest normalized state
Callback vs status lookup​
- Callback: push-style request snapshot
- Status lookup: pull-style current state by
payment_details_id
If callback delivery and polling disagree temporarily, prefer the latest successful GET /payments/status result as the operational source of truth.