This request requires a valid access token. See Authentication to obtain one with
POST /v1/auth/token before you continue.Request fields
Same shape as a purchase:request_id, amount, card, channel, plus optional order_reference (up to 128 characters) and reason (up to 200 characters) for your own records.
Amounts are always integers in the currency’s minor unit. For example,
5000 for SGD means SGD 50.00.Steps
1
Issue the refund
Use a secret key scoped to If the operation isn’t enabled for your outlet, see Fix operations unavailable for your outlet.
transaction-refund-unreferenced. The outlet must also be enabled for standalone refunds at the acquirer/terminal level. API reference.Handle the result
Any 2xx response is a result you must branch onstatus — never on response_code (that’s the verbatim host/acquirer code; useful for support tickets, not for your app logic).
PENDING means the outcome isn’t known yet — most often after a processor timeout. Don’t assume success or failure. Recover it one of two ways:
- Wait for a webhook (
payment.*,authorization.*,refund.*— see Webhook event types). - Call
GET /v1/transactions/{id}/statusfor a live inquiry against the acquirer.
id yet — a client-side timeout before the first response arrived — replay the same request with the same request_id and body. The replay returns the stored transaction and its id, whatever status it’s reached. Never re-submit with a new idempotency key just because the first attempt is slow — that risks a second charge for the same order.
Unlike a referenced refund, a standalone refund is a create-type operation: it returns 201 on success (and on a replay with the same request_id), matching purchase and authorize.
Errors
Full HTTP status and meaning for each of these is defined once on Problem format and retries — this list is only the standalone-refund-specific nuance:auth:insufficient-scope— your key’s token doesn’t have thetransaction-refund-unreferencedscoperouting:operation-disabled— standalone refunds aren’t enabled for any terminal that can route this requestdevice:operation-not-supported— the routed terminal has this operation toggled offgateway:validation-errortransaction:idempotency-body-mismatch— same body-hash comparison as purchase and authorize:request_id,amount,currency,payment_method_type,channel_type, the card’span_prefix(first 8 digits, not the full token),metadata, andorder_referenceare hashed and compared.reasonand the full card token aren’t hashed, so changing either on a retry still replays the original silently.
Voiding a standalone refund
A standalone refund is its own transaction and follows the same void-or-refund rule as any other capture: you can void it while its settlement batch is still open, and you can’t once it closes.Monitoring
Because a leaked or over-scoped key can issue standalone refunds silently, treat refund volume and amount as a security signal, not just a finance one:- Alert on any standalone refund above your normal order size, or on a burst of them in a short window.
- Reconcile standalone refunds against a real business reason (the goodwill credit, the chargeback case) — an unexplained one is an incident, not a bookkeeping question.
- Review who holds keys scoped to
transaction-refund-unreferencedon a regular cadence, and remove the scope from any key that doesn’t need it.
Test your integration
See Test your integration once enablement is confirmed for your sandbox outlet.Go-live notes
- Request a key scoped to only
transaction-refund-unreferenced(not a general-purpose key) for whatever service issues these refunds. - Log every standalone refund with the business reason before you call the API, not after.
- Review the full go-live checklist.
Next steps
Refund a payment
Use the referenced refund whenever an original transaction exists.
Security and PCI scope
Key storage, rotation, and emergency revocation guidance.