Refund a card payment
Refund a card payment without naming the processor — Tonder resolves it server-side from the transaction reference. Direct API and Web SDK integrations only.
Authorization
Authorization Tu API key con prefijo Token , p. ej. Token <API_KEY>
In: header
Path Parameters
Your business id — the number that appears in your dashboard URL and in Hosted Checkout session ids (cs_97_…).
The unique reference of the original card payment. Required for card transactions.
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
curl -X POST "https://example.com/business/97/payments/ch_3AbcDEFghiJKLmnO/refunds" \ -H "Content-Type: application/json" \ -d '{ "amount": 100 }'[
{
"id": 123,
"amount": 100,
"country": "MX",
"currency_code": "MXN",
"transaction_status": "success",
"checkout_id": "ch_3AbcDEFghiJKLmnO",
"is_apm": false
}
]{
"detail": "Authentication credentials were not provided."
}Before you integrate
Who can call it. Only Direct API and Web SDK (@tonder.io/web-sdk) integrations.
Hosted Checkout, the mobile SDKs and the legacy web SDK refund from the
dashboard — there is no other endpoint for them.
Cards only. SPEI, OXXO Pay, cash vouchers and Mercado Pago payments cannot be refunded through this endpoint.
Where the values come from
| Value | Where to find it |
|---|---|
business_id | Your business id — the number in your dashboard URL and in Hosted Checkout session ids (cs_97_…). |
transaction_reference | The unique reference of the original card payment. |
amount | The amount to refund, in the original transaction's currency, in decimal units (100.00). |
Read the response type, not the status code
A refund answers HTTP 200 with a JSON array holding one refund transaction:
[
{
"id": 123,
"amount": 100.00,
"country": "MX",
"currency_code": "MXN",
"transaction_status": "success",
"checkout_id": "ch_3AbcDEFghiJKLmnO",
"is_apm": false
}
]There is no 404. When nothing matches transaction_reference, the endpoint still answers
HTTP 200 — with the plain string "No payment transaction found to be refunded" instead of the
array. Branch on the response type: an array is a refund, a string is not-found.
On a 500, look before you retry
Provider failures surface as HTTP 500. A refund is not idempotent, so before re-sending, read the
original transaction with GET /transactions/{transaction_id}/
and retry only if it is still unrefunded — then with exponential backoff.
Direct API integrations can also refund through POST /process/ with operation_type: "refund"
— see Refunds. Either path, never both for the same payment.
