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.

POST
/business/{business_id}/payments/{transaction_reference}/refunds

Authorization

Authorization
Authorization<token>

Tu API key con prefijo Token , p. ej. Token <API_KEY>

In: header

Path Parameters

business_id*string

Your business id — the number that appears in your dashboard URL and in Hosted Checkout session ids (cs_97_…).

transaction_reference*string

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."
}
Empty

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

ValueWhere to find it
business_idYour business id — the number in your dashboard URL and in Hosted Checkout session ids (cs_97_…).
transaction_referenceThe unique reference of the original card payment.
amountThe 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.

Was this page helpful?