Postbacks
If you send a postbackUrl, the gateway calls it with POST when the payment reaches a final status.
Payload
Section titled “Payload”{ "transactionUuid": "caa8c25a-e7c1-490d-8d6", "paymentUuid": "pay_8f2c1d0e5a7b", "type": "DEPOSIT", "status": "APPROVED", "amount": "10.0", "currencyIso3": "USD", "message": "Approved", "referenceCode": "ORDER-2026-000123"}type is DEPOSIT or REFUND. status is APPROVED, DECLINED, ERROR or PENDING. Note that amount is
formatted as a number (10.0), not padded to two decimals.
Delivery
Section titled “Delivery”- Headers:
Content-Type: application/jsonandX-Idempotency-Key: <transactionUuid>. - Your server must answer 2xx. Anything else, or a timeout, is a failed attempt.
- Failed attempts are retried with increasing delays (1, 1, 2, 3, 5, 8, 13, 21 and 34 minutes), up to ten attempts.
- Redirects are not followed.
postbackUrl rules
Section titled “postbackUrl rules”It must be a public http(s) address on port 80 or 443, without credentials. Private IPs, localhost and other
ports are refused with 400 postbackUrl is not allowed: ... on a production gateway.
Write a safe handler
Section titled “Write a safe handler”- Answer 2xx fast, then do the work. Slow handlers cause retries.
- Be idempotent. The same postback can arrive more than once. Dedupe on
X-Idempotency-Keyor onreferenceCodeplusstatus. - Find the order by
referenceCode. - Do not trust the body alone. Postbacks are not signed. Before you ship goods, confirm the status with a lookup using your API key.
app.post('/payments/postback', express.json(), async (req, res) => { res.sendStatus(200); // answer first const { referenceCode } = req.body; const confirmed = await lookup(referenceCode); // POST /payment-Lookup with your key await markOrder(referenceCode, confirmed.status);});