Payment Webhooks
Example webhook bodies for payments, batch payments, maker-checker approvals and refunds.
See how to read the webhook examples. The values are made up, but every field, its order and its format match what Acme sends.
Payments
Successful payment (payments.succeeded):
{
"id": "wbh_0RWF7FTX5Y711",
"createdAt": "2026-10-08T02:11:46.917522108Z",
"mode": "LIVE",
"event": "payments.succeeded",
"object": {
"id": "pymt_0RWF7FTTNY6RR",
"type": "FAST",
"amount": 245000,
"currency": "SGD",
"customerReference": "INV-2026-10-0412",
"senderAccountId": "intacc_0QK7M2D4XH1PZ",
"receiver": {
"name": "TAN WEI MING",
"bank": "OCBCSGSGXXX",
"bankAccountNumber": "5012846731"
},
"paymentDetails": "Invoice 0412 payment",
"currencyExchange": {
"fxContractId": null
},
"senderAccountCurrency": "SGD",
"status": "COMPLETED",
"resultCode": null,
"bankReference": null,
"bankReferences": {},
"createdAt": "2026-10-08T02:11:40.318Z",
"updatedAt": "2026-10-08T02:11:46.902Z"
}
}These fields are left out when they have no value:
- In
receiver: any field without a value, such asbankandbankAccountNumberfor a proxy payment, orproxyTypeandproxyValuefor an account payment bankChargeBearer,instructionForSenderBank,underlyingErrorMessageandpaymentAdviceEmailsbatchIdandpaymentDate, for a payment that is not part of a batchactualPaymentDate,bankChargeAmountandbankChargeCurrency, which are sent for a payment in a batch once the bank reports themreview, which is sent only with the four maker-checker events
Other details you sent when you created the payment, such as purposeCode, are also returned as
extra fields in the payment and in receiver.
bankReference and bankReferences are filled only when the bank returns a reference. The keys in
bankReferences are the bank's own field names.
Failed payment (payments.failed):
{
"id": "wbh_0RWF7FV9NY7AF",
"createdAt": "2026-10-08T02:12:05.115370442Z",
"mode": "LIVE",
"event": "payments.failed",
"object": {
"id": "pymt_0RWF7FV9DY443",
"type": "FAST",
"amount": 245000,
"currency": "SGD",
"customerReference": "INV-2026-10-0413",
"senderAccountId": "intacc_0QK7M2D4XH1PZ",
"receiver": {
"name": "TAN WEI MING",
"bank": "OCBCSGSGXXX",
"bankAccountNumber": "5012846739"
},
"paymentDetails": "Invoice 0413 payment",
"currencyExchange": {
"fxContractId": null
},
"senderAccountCurrency": "SGD",
"status": "FAILED",
"resultCode": "INVALID_ACCOUNT",
"underlyingErrorMessage": "1010 Payer/payee account is incorrect",
"bankReference": null,
"bankReferences": {},
"createdAt": "2026-10-08T02:11:58.404Z",
"updatedAt": "2026-10-08T02:12:05.101Z"
}
}Payments in a batch
Payments in a batch are sent with payments.succeeded or payments.failed:
- They are sent when Acme processes the bank's acknowledgement file, with several payments under
objects. - One webhook carries up to 100 payments. A larger batch is split across several webhooks.
- The bank can confirm some payments before others. Each webhook then carries the payments confirmed so far, and the rest arrive in later webhooks.
- A webhook can also carry a single payment under
object. Accept bothobjectandobjects. - Process each payment on its own, by its
id. Do not rely on its position in the array.
{
"id": "wbh_0RWF7FVA9Y6FQ",
"createdAt": "2026-10-09T01:12:44.873519027Z",
"mode": "LIVE",
"event": "payments.succeeded",
"objects": [
{
"id": "pymt_0RWF7FVA5Y52Q",
"type": "GIRO",
"amount": 420000,
"currency": "SGD",
"customerReference": "SAL-OCT26-0001",
"senderAccountId": "intacc_0QK7M2D4XH1PZ",
"receiver": {
"name": "TAN WEI MING",
"bank": "OCBCSGSGXXX",
"bankAccountNumber": "5012846731"
},
"batchId": "bpmt_0QK7N8V2FB3RT",
"paymentDate": "2026-10-09",
"paymentDetails": "Salary Oct 2026",
"currencyExchange": {
"fxContractId": null
},
"senderAccountCurrency": "SGD",
"status": "COMPLETED",
"resultCode": null,
"bankReference": null,
"bankReferences": {},
"createdAt": "2026-10-08T09:02:11.481Z",
"updatedAt": "2026-10-09T01:12:44.861Z"
},
{
"id": "pymt_0RWF7FVA5Y52S",
"type": "GIRO",
"amount": 385000,
"currency": "SGD",
"customerReference": "SAL-OCT26-0002",
"senderAccountId": "intacc_0QK7M2D4XH1PZ",
"receiver": {
"name": "NUR AISYAH BINTE RAHMAN",
"bank": "UOVBSGSGXXX",
"bankAccountNumber": "3609127745"
},
"batchId": "bpmt_0QK7N8V2FB3RT",
"paymentDate": "2026-10-09",
"paymentDetails": "Salary Oct 2026",
"currencyExchange": {
"fxContractId": null
},
"senderAccountCurrency": "SGD",
"status": "COMPLETED",
"resultCode": null,
"bankReference": null,
"bankReferences": {},
"createdAt": "2026-10-08T09:02:11.481Z",
"updatedAt": "2026-10-09T01:12:44.861Z"
}
]
}Maker-checker flow
Payment waiting for approval (payments.pending-approval):
{
"id": "wbh_0RWF7FVB1Y5CA",
"createdAt": "2026-10-08T03:41:28.376879315Z",
"mode": "LIVE",
"event": "payments.pending-approval",
"object": {
"id": "pymt_0RWF7FVAXY5ZZ",
"type": "FAST",
"amount": 1100000,
"currency": "SGD",
"customerReference": "INV-2026-0429",
"senderAccountId": "intacc_0QK7M2D4XH1PZ",
"receiver": {
"name": "SUNRISE LOGISTICS PTE LTD",
"bank": "DBSSSGSGXXX",
"bankAccountNumber": "0039182746"
},
"paymentDetails": "Invoice 0429 payment",
"currencyExchange": {
"fxContractId": null
},
"senderAccountCurrency": "SGD",
"status": "PENDING_APPROVAL",
"resultCode": null,
"bankReference": null,
"bankReferences": {},
"createdAt": "2026-10-08T03:41:26.929Z",
"updatedAt": "2026-10-08T03:41:26.929Z",
"review": {
"requestedBy": "ak_finance_maker",
"approvedAt": null,
"approvedBy": null,
"rejectedAt": null,
"rejectedBy": null,
"rejectionReason": null,
"expiresAt": "2026-10-09T03:41:26.929745Z"
}
}
}Payment approved (payments.approved). It carries the payment as it stands after Acme submits it to
the bank:
statusis usuallyPROCESSING. Apayments.succeededorpayments.failedwebhook follows when the bank settles the payment.- When the bank answers at once,
statuscan already beCOMPLETEDorFAILED. Thepayments.succeededorpayments.failedwebhook can then arrive before this one. - When Acme could not submit the payment,
statuscan still bePENDING_APPROVAL.
{
"id": "wbh_0RWF7FVBNY6D4",
"createdAt": "2026-10-08T04:12:55.110044791Z",
"mode": "LIVE",
"event": "payments.approved",
"object": {
"id": "pymt_0RWF7FVAXY5ZZ",
"type": "FAST",
"amount": 1100000,
"currency": "SGD",
"customerReference": "INV-2026-0429",
"senderAccountId": "intacc_0QK7M2D4XH1PZ",
"receiver": {
"name": "SUNRISE LOGISTICS PTE LTD",
"bank": "DBSSSGSGXXX",
"bankAccountNumber": "0039182746"
},
"paymentDetails": "Invoice 0429 payment",
"currencyExchange": {
"fxContractId": null
},
"senderAccountCurrency": "SGD",
"status": "PROCESSING",
"resultCode": null,
"bankReference": null,
"bankReferences": {},
"createdAt": "2026-10-08T03:41:26.929Z",
"updatedAt": "2026-10-08T04:12:55.004Z",
"review": {
"requestedBy": "ak_finance_maker",
"approvedAt": "2026-10-08T04:12:54.882011Z",
"approvedBy": "Jane Lim",
"rejectedAt": null,
"rejectedBy": null,
"rejectionReason": null,
"expiresAt": "2026-10-09T03:41:26.929745Z"
}
}
}Approval rejected (payments.approval-rejected):
{
"id": "wbh_0RWF7FVBSY56Q",
"createdAt": "2026-10-08T04:30:12.554302178Z",
"mode": "LIVE",
"event": "payments.approval-rejected",
"object": {
"id": "pymt_0RWF7FVAXY5ZZ",
"type": "FAST",
"amount": 1100000,
"currency": "SGD",
"customerReference": "INV-2026-0429",
"senderAccountId": "intacc_0QK7M2D4XH1PZ",
"receiver": {
"name": "SUNRISE LOGISTICS PTE LTD",
"bank": "DBSSSGSGXXX",
"bankAccountNumber": "0039182746"
},
"paymentDetails": "Invoice 0429 payment",
"currencyExchange": {
"fxContractId": null
},
"senderAccountCurrency": "SGD",
"status": "APPROVAL_REJECTED",
"resultCode": null,
"bankReference": null,
"bankReferences": {},
"createdAt": "2026-10-08T03:41:26.929Z",
"updatedAt": "2026-10-08T04:30:12.231Z",
"review": {
"requestedBy": "ak_finance_maker",
"approvedAt": null,
"approvedBy": null,
"rejectedAt": "2026-10-08T04:30:12.231019Z",
"rejectedBy": "Jane Lim",
"rejectionReason": "Beneficiary not on approved vendor list",
"expiresAt": "2026-10-09T03:41:26.929745Z"
}
}
}Approval expired (payments.approval-expired):
{
"id": "wbh_0RWF7FVBXY6F9",
"createdAt": "2026-10-09T03:41:30.001284507Z",
"mode": "LIVE",
"event": "payments.approval-expired",
"object": {
"id": "pymt_0RWF7FVAXY5ZZ",
"type": "FAST",
"amount": 1100000,
"currency": "SGD",
"customerReference": "INV-2026-0429",
"senderAccountId": "intacc_0QK7M2D4XH1PZ",
"receiver": {
"name": "SUNRISE LOGISTICS PTE LTD",
"bank": "DBSSSGSGXXX",
"bankAccountNumber": "0039182746"
},
"paymentDetails": "Invoice 0429 payment",
"currencyExchange": {
"fxContractId": null
},
"senderAccountCurrency": "SGD",
"status": "APPROVAL_EXPIRED",
"resultCode": null,
"bankReference": null,
"bankReferences": {},
"createdAt": "2026-10-08T03:41:26.929Z",
"updatedAt": "2026-10-09T03:41:30.001Z",
"review": {
"requestedBy": "ak_finance_maker",
"approvedAt": null,
"approvedBy": null,
"rejectedAt": null,
"rejectedBy": null,
"rejectionReason": null,
"expiresAt": "2026-10-09T03:41:26.929745Z"
}
}
}In review, requestedBy, approvedBy and rejectedBy say who took that step:
- For an API key, its name, or its ID when the key has no name.
- For a dashboard user, their name, or their email until they have set a name.
Batch Payments
Batch payment submitted (payment-batches.submitted):
{
"id": "wbh_0RWF7FVP1Y763",
"createdAt": "2026-10-08T09:05:37.218394502Z",
"mode": "LIVE",
"event": "payment-batches.submitted",
"object": {
"id": "bpmt_0QK7N8V2FB3RT",
"type": "GIRO",
"paymentDate": "2026-10-09",
"senderAccountId": "intacc_0QK7M2D4XH1PZ",
"senderAccountCurrency": "SGD",
"currency": "SGD",
"status": "SUBMITTED",
"metadata": {
"fileName": "UFF1_ROCKETSG01_20261008_0905.txt"
},
"createdAt": "2026-10-08T09:02:11.481Z",
"updatedAt": "2026-10-08T09:05:37.206Z"
}
}Batch payment rejected (payment-batches.rejected). underlyingErrorMessage is the bank's reason:
{
"id": "wbh_0RWF7FVPSY5H8",
"createdAt": "2026-10-08T09:21:03.790126518Z",
"mode": "LIVE",
"event": "payment-batches.rejected",
"object": {
"id": "bpmt_0QK7N8V2FB3RT",
"type": "GIRO",
"paymentDate": "2026-10-09",
"senderAccountId": "intacc_0QK7M2D4XH1PZ",
"senderAccountCurrency": "SGD",
"currency": "SGD",
"status": "FAILED",
"underlyingErrorMessage": "ACK2007 Duplicate BatchId",
"metadata": {
"fileName": "UFF1_ROCKETSG01_20261008_0905.txt"
},
"createdAt": "2026-10-08T09:02:11.481Z",
"updatedAt": "2026-10-08T09:21:03.774Z"
}
}Refunds
Successful refund (refunds.succeeded):
{
"id": "wbh_0RWF7FVRSY4SH",
"createdAt": "2026-10-08T09:50:25.426288002Z",
"mode": "LIVE",
"event": "refunds.succeeded",
"object": {
"id": "rfnd_0RWF7FVRHY6GG",
"transactionId": "txn_0QK6ZB1R4T8WM",
"amount": 1240,
"currency": "SGD",
"status": "SUCCEEDED",
"resultCode": null,
"createdAt": "2026-10-08T09:50:20.414Z",
"updatedAt": "2026-10-08T09:50:25.421Z"
}
}Failed refund (refunds.failed):
{
"id": "wbh_0RWF7FVSNY74X",
"createdAt": "2026-10-08T09:50:58.068242142Z",
"mode": "LIVE",
"event": "refunds.failed",
"object": {
"id": "rfnd_0RWF7FVSDY7D4",
"transactionId": "txn_0QK6ZC7X2N5DE",
"amount": 15000,
"currency": "SGD",
"status": "FAILED",
"resultCode": "REQUESTED_REFUND_AMOUNT_EXCEEDS_REFUNDABLE_AMOUNT",
"createdAt": "2026-10-08T09:50:53.053Z",
"updatedAt": "2026-10-08T09:50:58.059Z"
}
}