Retiros
Envía dinero a un beneficiario por SPEI o tarjeta de débito, apruébalo y síguelo hasta la liquidación: cómo crearlo, los dos vocabularios de estados, los webhooks y los datos de prueba.
Los retiros (payouts) envían dinero de tu saldo a la CLABE de 18 dígitos de un beneficiario por SPEI, o a una tarjeta de débito de 16 dígitos. Están disponibles para beneficiarios en México, en MXN. Para pagos en Argentina (ARS) a una CBU, CVU o alias, consulta Argentina; para pagos en Chile (CLP) a una cuenta corriente o vista, consulta Retiros en Chile.
Esta guía está dirigida a quien va a integrar. Cubre la creación de un retiro y el resto del ciclo: aprobación, consulta, estados y webhooks.
Tonder elige el riel. El proveedor que ejecuta la transferencia lo resuelve Tonder según la configuración de tu comercio. No necesitas conocerlo ni construir lógica sobre él: puede cambiar sin que tengas que modificar tu integración.
| Aspecto | SPEI | Tarjeta de débito |
|---|---|---|
| Tiempo de procesamiento | Instantáneo (segundos) | Instantáneo (segundos) |
| Disponibilidad | 24/7 | 24/7 |
| Destino | CLABE de 18 dígitos | Tarjeta de 16 dígitos |
| Ideal para | Beneficiarios con CLABE, montos mayores | Beneficiarios que solo tienen tarjeta |
Ambientes y autenticación
Los retiros viven en el host de API Direct:
| Servicio | Sandbox | Producción |
|---|---|---|
| API Direct (S2S) | https://stage.tonder.io/api/v1/ | https://app.tonder.io/api/v1/ |
| Hosted Checkout | https://api-stage.tonder.io/checkout/v1/ | https://api.tonder.io/checkout/v1/ |
| Depósitos SPEI (CLABE por usuario) | https://api-stage.tonder.io/deposits/ | https://api.tonder.io/deposits/ |
| Tokenización de tarjetas | https://token-sandbox.tonder.io/ | https://token.tonder.io/ |
| Datos de tarjeta en crudo (PCI L1) | https://process-sandbox.tonder.io/ | https://process.tonder.io/ |
| Dashboard | https://dashboard-stage.tonder.io/ | https://dashboard.tonder.io/ |
Cada petición lleva la API key pública de tu comercio. La privada no sirve para este flujo.
Authorization: Token <API_KEY>
Content-Type: application/json| Caso | Respuesta |
|---|---|
Sin cabecera Authorization | 401 · Authentication credentials were not provided. |
| Token inexistente | 401 · Invalid token. |
| Token de un usuario deshabilitado | 401 · User inactive or deleted. |
Crear un retiro
Créalo con POST /api/v1/process/, el mismo endpoint que usan los pagos. Lo que distingue a un
retiro es operation_type.
curl -X POST "https://stage.tonder.io/api/v1/process/" \
-H "Authorization: Token YOUR_TEST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"operation_type": "withdrawal",
"amount": 20.00,
"currency": "MXN",
"client_reference": "payout-001",
"transfer_method": "SPEI",
"description": "Pago de comisiones",
"beneficiary": {
"account": "012969100000000110",
"name": "Ana Maria Gonzalez",
"rfc": "GOAN850315AB2",
"institution": "40012",
"email": "ana.gonzalez@email.com"
},
"metadata": {
"latitude": "22.8870221",
"longitude": "-109.911775",
"order_reference": "ORD-001"
},
"fee_model": "01"
}'curl -X POST "https://app.tonder.io/api/v1/process/" \
-H "Authorization: Token YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"operation_type": "withdrawal",
"amount": 20.00,
"currency": "MXN",
"client_reference": "payout-001",
"transfer_method": "SPEI",
"description": "Pago de comisiones",
"beneficiary": {
"account": "012969100000000110",
"name": "Ana Maria Gonzalez",
"rfc": "GOAN850315AB2",
"institution": "40012",
"email": "ana.gonzalez@email.com"
},
"metadata": {
"latitude": "22.8870221",
"longitude": "-109.911775",
"order_reference": "ORD-001"
},
"fee_model": "01"
}'| Campo | Obligatorio | Descripción |
|---|---|---|
operation_type | sí | Siempre "withdrawal" |
amount | sí | Monto. Debe ser mayor que cero |
currency | sí | "MXN". Argentina usa "ARS" —consulta Argentina—; Chile usa "CLP" —consulta Retiros en Chile |
transfer_method | sí | "SPEI" o "DEBIT_CARD"; "BANK_TRANSFER" en Argentina; "CLP_TRANSFER" en Chile |
client_reference | recomendado | Tu referencia interna. Vuelve en la respuesta y en los webhooks |
description | no | Concepto del pago. Si lo omites queda como Retiro de fondos |
beneficiary.account | sí | CLABE de 18 dígitos para SPEI, tarjeta de 16 para débito |
beneficiary.name | sí | Nombre del titular, como aparece en su cuenta |
beneficiary.rfc | sí | RFC o CURP del beneficiario. Si no lo tienes, envía "ND" |
beneficiary.institution | sí | Código de institución de Banxico. Ver Códigos de institución |
beneficiary.email | sí | Correo del beneficiario |
metadata | no | Información tuya. Se guarda y se devuelve tal cual |
fee_model | sí | "01" |
Tarjeta de débito. Respecto a SPEI cambian dos cosas y nada más: transfer_method pasa a
"DEBIT_CARD" y beneficiary.account lleva el número de 16 dígitos.
Geolocalización. metadata.latitude y metadata.longitude se recomiendan para operaciones
en México. Si tu integración ya las envía, mantenlas.
HTTP 201:
{
"id": "a1e2f918-1851-4988-b9de-36d57f41ed56",
"withdrawal_id": "ad3069ed-598e-4a1b-82e0-2279d5af292d",
"operation_type": "withdrawal",
"status": "Pending",
"amount": 20.0,
"currency": "MXN",
"client_reference": "payout-001",
"metadata": {
"latitude": "22.8870221",
"longitude": "-109.911775",
"order_reference": "ORD-001"
},
"transfer_method": "SPEI",
"created_at": "2026-10-01T17:33:41.364685Z",
"status_code": 201
}Guarda los dos identificadores, son distintos y no son intercambiables.
withdrawal_id es el del retiro: aprobar, rechazar, consultar el detalle.
id es el de la transacción: consultar el estado de la operación.
Aprobar
Un retiro recién creado queda en estado pendiente y no avanza solo, salvo que tu comercio tenga activada una regla de aprobación automática. Si tus retiros se quedan ahí, este es el paso que falta.
Desde el Dashboard. Abre el retiro en Retiros y presiona Approve.
Por API:
curl -X POST "https://stage.tonder.io/api/v1/withdrawals/perform_action/" \
-H "Authorization: Token YOUR_TEST_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "id": "ad3069ed-598e-4a1b-82e0-2279d5af292d", "action": "approve" }'curl -X POST "https://app.tonder.io/api/v1/withdrawals/perform_action/" \
-H "Authorization: Token YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "id": "ad3069ed-598e-4a1b-82e0-2279d5af292d", "action": "approve" }'Cuidado con cuál identificador envías aquí. Es el withdrawal_id de la respuesta de
/process/, no su id.
Enviar el id devuelve 404 Withdrawal not found: 'Item', que despista porque suena a que el
retiro no existe.
Acciones: approve, reject, cancel, fail, refund.
Idempotencia. Un segundo approve sobre un retiro ya liquidado responde 409 con
Invalid transition from PAID_FULL to PROCESSING. Sobre uno en estado terminal, 409 con
Cannot modify withdrawal in terminal state. Reintentar no duplica el pago.
Una acción inexistente responde 400 con Invalid action.
Consultar
Estado de la transacción
GET /api/v1/transactions/<id>/Toma el id de transacción, el campo id de la respuesta de /process/.
Detalle del retiro
curl "https://stage.tonder.io/api/v1/withdrawals/ad3069ed-598e-4a1b-82e0-2279d5af292d" \
-H "Authorization: Token YOUR_TEST_API_KEY"curl "https://app.tonder.io/api/v1/withdrawals/ad3069ed-598e-4a1b-82e0-2279d5af292d" \
-H "Authorization: Token YOUR_API_KEY"Sin barra final. Con barra responde 404. Un identificador inexistente responde 200 con
{"detail": "Withdrawal not found"} y sin registro: comprueba detail antes de leer los campos.
Es el único endpoint que trae el motivo de un fallo, en status_changes[].reason y
action.reason:
{
"id": "7b57edd2-6594-4ef6-813b-df0d3d091a5c",
"business_id": "69",
"status": "FAILED",
"amount": 1.7,
"currency": "MXN",
"transfer_method": "SPEI",
"tracking_key": "a61c4f05b1de4645a1d2",
"provider_reference": null,
"account_data": { "...": "..." },
"status_changes": [
{ "from_status": "PENDING", "to_status": "PROCESSING",
"timestamp": "2026-10-13T18:40:23.497368", "reason": null },
{ "from_status": "PROCESSING", "to_status": "FAILED",
"timestamp": "2026-10-13T18:40:23.497375",
"reason": "Provider rejected: invalid_institution_id" }
],
"action": { "action": "FAIL", "reason": "Provider rejected: invalid_institution_id" },
"url_cep": "",
"created_at": "2026-10-13T02:06:17.772297Z",
"paid_at": null
}Listado
curl "https://stage.tonder.io/api/v1/withdrawals/query/?page=1&page_size=50&start_date=2026-10-01&end_date=2026-10-07" \
-H "Authorization: Token YOUR_TEST_API_KEY"curl "https://app.tonder.io/api/v1/withdrawals/query/?page=1&page_size=50&start_date=2026-10-01&end_date=2026-10-07" \
-H "Authorization: Token YOUR_API_KEY"| Parámetro | |
|---|---|
page, page_size | Paginación |
start_date, end_date | Rango, formato AAAA-MM-DD |
La respuesta es { "count", "results", "search_mode" }, donde cada elemento de results es el
registro completo del retiro, el mismo del detalle.
El filtro por id no está soportado: se ignora en silencio y devuelve el listado completo.
Para un retiro concreto usa el detalle de arriba.
Un rango invertido, con start_date posterior a end_date, devuelve 500.
Saldo disponible
curl "https://stage.tonder.io/api/v1/withdrawals/balance" \
-H "Authorization: Token YOUR_TEST_API_KEY"curl "https://app.tonder.io/api/v1/withdrawals/balance" \
-H "Authorization: Token YOUR_API_KEY"{
"available": "32894.55",
"current_balance": "32894.55"
}Solo GET. Con POST responde 405.
La forma de la respuesta depende de la configuración de tu comercio. Puede traer solo
current_balance, o current_balance junto a available. Léelo de forma defensiva y no asumas
que ambos campos existen.
Movimientos de cuenta
curl "https://stage.tonder.io/api/v1/withdrawals/account_activity/query/?page=1&page_size=50&tz=America/Mexico_City&start_date=2026-10-01&end_date=2026-10-02" \
-H "Authorization: Token YOUR_TEST_API_KEY"curl "https://app.tonder.io/api/v1/withdrawals/account_activity/query/?page=1&page_size=50&tz=America/Mexico_City&start_date=2026-10-01&end_date=2026-10-02" \
-H "Authorization: Token YOUR_API_KEY"Devuelve los movimientos de la cuenta, retiros y depósitos, como { "results", "next_token" }.
El rango debe abarcar al menos dos días. Con start_date igual a end_date devuelve lista
vacía aunque ese día tenga movimientos. Para consultar un solo día, pon el día siguiente como
end_date.
Los movimientos entran por dos caminos: uno inmediato, de segundos, y una reconciliación horaria que completa algunos campos. Un movimiento recién pagado puede tardar hasta una hora en mostrarse completo.
Estados
El ciclo completo, en el orden en que ocurren:
| Estado | Tipo | Qué significa |
|---|---|---|
PENDING | Inicial | Creado. Esperando aprobación |
PROCESSING | Intermedio | Aprobado, en curso interno |
SENT_TO_PROVIDER | Intermedio | Enviado. Sin confirmación todavía |
PAID_FULL | Terminal | Liquidado |
FAILED | Terminal | Falló. El detalle trae el motivo |
REJECTED | Terminal | Rechazado, por ti o por validación |
CANCELED | Terminal | Cancelado |
REFUNDED | Terminal | Se pagó, y el banco receptor devolvió los fondos |
Dos vocabularios
La respuesta de creación y los webhooks usan nombres en formato legible, mientras que las consultas devuelven los nombres internos. Son el mismo estado:
| En la creación y los webhooks | En las consultas |
|---|---|
Pending | PENDING |
Processing | PROCESSING / SENT_TO_PROVIDER |
Success | PAID_FULL |
Declined | REJECTED |
Cancelled | CANCELED |
Failed | FAILED |
Returned | REFUNDED |
Contempla los dos. Si tu integración solo reconoce uno de los conjuntos, va a ignorar eventos reales.
Al conciliar
PROCESSING y SENT_TO_PROVIDER son intermedios. Dar por bueno un retiro al verlos produce
resultados equivocados. Espera siempre un estado terminal.
Trata REFUNDED como final y acredita la reversión. Un retiro devuelto pasó antes por
PAID_FULL, así que una lógica que solo reaccione al pago nunca verá que el dinero volvió.
Los cinco terminales son PAID_FULL, FAILED, REJECTED, CANCELED y REFUNDED. Concilia
contra los cinco.
Webhooks
Se emiten dos por retiro: uno al crearse, con estado pendiente, y otro al llegar a estado terminal. Si los fondos se devuelven después de haberse pagado, llega un tercero.
Hay dos formatos de carga, y cuál recibes depende de cómo esté configurado tu comercio. Confírmalo con nosotros antes de escribir el manejador. Los dos traen la misma información esencial: estado, método, monto y tus referencias.
Formato plano
{
"id": "a1e2f918-1851-4988-b9de-36d57f41ed56",
"operation_type": "withdrawal",
"amount": "20",
"currency": "MXN",
"client_reference": "payout-001",
"status": "Pending",
"transfer_method_type": "SPEI",
"created": "2026-05-21T19:15:32.029134Z",
"metadata": {
"latitude": "22.8870221",
"longitude": "-109.911775",
"external_id": "payout-001"
},
"event_type": "withdrawal_Pending",
"action": "MODIFY"
}| Campo | |
|---|---|
id | Id de transacción. Se repite en cada evento del mismo retiro: es el que te permite correlacionar |
operation_type | "withdrawal" |
status | Estado alcanzado |
transfer_method_type | SPEI o DEBIT_CARD |
event_type | withdrawal_ más el estado |
client_reference | Tu referencia, tal como la enviaste |
metadata | Lo que enviaste, más external_id |
action | "MODIFY" |
La carga puede traer otros campos que identifican a la institución que ejecutó la transferencia y su referencia. No construyas lógica sobre ellos: dependen de la configuración de tu cuenta y pueden cambiar.
Formato extendido
Anida todo bajo withdrawal y agrega el historial de estados, las comisiones y el detalle del
envío. El estado viaja en los nombres internos de la sección Estados.
{
"withdrawal": {
"id": "ad3069ed-598e-4a1b-82e0-2279d5af292d",
"business_id": "69",
"status": "PAID_FULL",
"business_id_status": "69#PAID_FULL",
"monetary_amount": { "amount": "20.00", "currency": "MXN" },
"transfer_method": "SPEI",
"tracking_key": "2da0310418da4be18419",
"provider_reference": "ref_2da0310418da4be1",
"account_data": {
"nombre_beneficiario": "Ana Maria Gonzalez",
"cuenta_beneficiario": "012969100000000110",
"institucion_contraparte": "40012",
"tipo_cuenta_beneficiario": "40",
"rfc_curp_beneficiario": "GOAN850315AB2",
"concepto_pago": "Pago de comisiones",
"email": "ana.gonzalez@email.com"
},
"status_changes": [
{ "from_status": "PENDING", "to_status": "PROCESSING",
"timestamp": "2026-09-15T19:33:20.112", "reason": null },
{ "from_status": "PROCESSING", "to_status": "PAID_FULL",
"timestamp": "2026-09-15T19:35:52.912", "reason": "succeeded" }
],
"metadata": { "order_reference": "ORD-001" },
"fee_model": "01",
"created_at": "2026-09-15T19:33:14.262113+00:00",
"modified_at": "2026-09-15T19:35:52.989243+00:00",
"paid_at": "2026-09-15T19:35:52.989260+00:00"
}
}Trae además un bloque con la notificación cruda de la institución que ejecutó el envío.
Dentro de ese bloque el monto va en centavos, a diferencia de monetary_amount, que va en
pesos. Y puede traer una clave de rastreo distinta de la de nivel superior: esa segunda es la clave
SPEI real ante Banxico, la que sirve para rastrear el pago en su portal. Los datos del beneficiario
llegan enmascarados.
Los cinco eventos
withdrawal_Pending — el retiro se creó y espera aprobación.
{ "status": "Pending", "event_type": "withdrawal_Pending", "...": "..." }withdrawal_Success — liquidado. El dinero salió.
{ "status": "Success", "event_type": "withdrawal_Success", "...": "..." }withdrawal_Declined — rechazado, normalmente por datos del beneficiario.
{ "status": "Declined", "event_type": "withdrawal_Declined", "...": "..." }withdrawal_Failed — falló al enviarse.
{ "status": "Failed", "event_type": "withdrawal_Failed", "...": "..." }withdrawal_Returned — el banco receptor devolvió los fondos después de un pago exitoso. Es
el tercer webhook de ese retiro, y llega minutos u horas después del Success.
{ "status": "Returned", "event_type": "withdrawal_Returned", "...": "..." }Con Webhooks 2.0, un retiro cancelado también
envía withdrawal_Canceled —con una sola L.
Recomendaciones
Sé idempotente. Un mismo evento puede llegar más de una vez. Con Webhooks 2.0, deduplica con el
header webhook-id; sin él, usa id junto con event_type como llave. metadata.external_id se
repite en cada evento del retiro, así que correlaciona pero no distingue Pending de Success.
No asumas orden. El terminal puede llegar antes que el pendiente.
Algunos campos identifican quién ejecutó la transferencia y con qué referencia. No construyas
lógica sobre esos valores: dependen de la configuración de tu cuenta y pueden cambiar. Para
reaccionar usa status, event_type y tus propios identificadores.
Responde 2xx rápido y procesa después. Concilia lo que tu endpoint no haya recibido con el
detalle del retiro; cómo se reintentan y reenvían las entregas
está en Entrega y reintentos.
Códigos de institución
beneficiary.institution es el código de la institución del beneficiario según el catálogo de
Banxico, de cuatro o cinco dígitos. También funcionan los participantes no bancarios del catálogo.
La lista completa está en la Referencia bancaria.
El código de institución y la CLABE deben corresponder al mismo banco. El sistema no verifica esa correspondencia al crear el retiro, pero una discrepancia puede provocar un rechazo al enviarlo.
Datos de prueba
Válidos únicamente en Sandbox, y siempre con la institución 40012: dos CLABEs que pagan,
una que falla, una cuyos fondos vuelven entre minutos y una hora después de pagarse —la forma de
ejercitar el tercer webhook, withdrawal_Returned— y una tarjeta de débito que paga. Las cuentas
y cómo forzar cada estado terminal están en
Casos de prueba — Retiros.
Si estos datos te son rechazados, escríbenos antes de seguir: puede ser que tu cuenta de pruebas requiera otra configuración.
Comprobante de pago (CEP)
Los retiros liquidados entregan un comprobante en el campo url_cep, que apunta al portal de
Banxico con los datos del pago.
Tarda entre 4 y 30 minutos en aparecer después de la liquidación. Consultarlo justo al aprobar devuelve vacío sin que eso signifique que falte. No concluyas nada antes de media hora.
Un retiro REFUNDED conserva su comprobante: el envío ocurrió y después se devolvió.
Errores
| Respuesta | Qué pasó |
|---|---|
400 · Amount must be greater than 0 | Monto en cero o negativo |
400 · Transfer method must be SPEI or DEBIT_CARD | Método no reconocido |
400 · beneficiary.account: This field is required | Falta la cuenta destino |
400 · Invalid action | La acción enviada no existe |
401 · Invalid token | API key incorrecta |
401 · User inactive or deleted | El usuario de esa key está deshabilitado |
404 · Withdrawal not found: 'Item' | Enviaste el id de transacción donde iba el withdrawal_id |
200 · {"detail": "Withdrawal not found"} | El identificador de la URL del detalle no existe (el detalle responde 200, no 404) |
405 · Method not allowed | El endpoint de saldo solo acepta GET |
409 · Invalid transition | El retiro ya está en un estado terminal |
Provider rejected: invalid_institution_id | El código de institución no corresponde |
Los códigos HTTP genéricos están en Códigos.
Antes de salir a producción
El monto no se valida contra tu saldo al crear. Un retiro por encima de lo disponible se acepta y queda pendiente. La validación ocurre al liquidarlo, y ahí falla.
El saldo no se reserva mientras el retiro está pendiente. Se descuenta al pagarse. Si acumulas muchos pendientes, el saldo disponible no refleja ese compromiso.
El nombre del beneficiario tiene un límite práctico de 40 caracteres. Nombres más largos pueden ser rechazados al enviar, no al crear. Conviene validarlo de tu lado antes. Un caso frecuente es el apellido duplicado por el usuario final.
Un retiro pendiente se despacha con la configuración vigente al aprobarlo, no con la que tenía al crearse.
El límite de monto lo define la institución que ejecuta la transferencia, no Tonder.
Dudas
Si algo de esta guía no coincide con lo que observas, escríbenos a
soporte con el withdrawal_id, el id de transacción y la hora
aproximada. Con eso podemos rastrear el caso completo.
Referencia de la API
Un retiro se crea con Procesar transacción. El resto del ciclo:
Autorización
Authorization Your public API key, with the word Token and a space in front of it. Example: Token 6534bc0a7e1f4d2b9c8e3a5f7b1d2c4e6f8a9b0c — that whole value is the header. Sending the key alone returns 401 'Authentication credentials were not provided'. In this playground you may paste just the key; the prefix is added for you.
In: header
Cuerpo de la petición
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Cuerpo de la respuesta
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/withdrawals/perform_action/" \ -H "Content-Type: application/json" \ -d '{ "id": "ad3069ed-598e-4a1b-82e0-2279d5af292d", "action": "approve" }'{
"id": "ad3069ed-598e-4a1b-82e0-2279d5af292d",
"business_id": "69",
"status": "PROCESSING",
"amount": 20,
"currency": "MXN",
"transfer_method": "SPEI",
"status_changes": [
{
"from_status": "PENDING",
"to_status": "PROCESSING",
"timestamp": "2026-10-01T17:35:02.118402",
"reason": null
}
],
"created_at": "2026-10-01T17:33:41.364685Z",
"modified_at": "2026-10-01T17:35:02.201173Z",
"paid_at": null
}{
"error": "Invalid action"
}{
"detail": "Invalid token."
}{
"error": "Withdrawal not found: 'Item'"
}{
"detail": "Cannot modify withdrawal in terminal state"
}Autorización
Authorization Your public API key, with the word Token and a space in front of it. Example: Token 6534bc0a7e1f4d2b9c8e3a5f7b1d2c4e6f8a9b0c — that whole value is the header. Sending the key alone returns 401 'Authentication credentials were not provided'. In this playground you may paste just the key; the prefix is added for you.
In: header
Parámetros de ruta
The withdrawal id: withdrawal_id from POST /process/.
Cuerpo de la respuesta
application/json
application/json
curl -X GET "https://example.com/withdrawals/7b57edd2-6594-4ef6-813b-df0d3d091a5c"{
"id": "7b57edd2-6594-4ef6-813b-df0d3d091a5c",
"business_id": "69",
"status": "FAILED",
"amount": 1.7,
"currency": "MXN",
"transfer_method": "SPEI",
"tracking_key": "a61c4f05b1de4645a1d2",
"provider_reference": null,
"account_data": {
"nombre_beneficiario": "Ana Maria Gonzalez",
"cuenta_beneficiario": "012969100000000013",
"institucion_contraparte": "40012",
"tipo_cuenta_beneficiario": 40,
"rfc_curp_beneficiario": "GOAN850315AB2",
"concepto_pago": "Pago de comisiones",
"email": "ana.gonzalez@email.com"
},
"metadata": {
"order_reference": "ORD-001"
},
"status_changes": [
{
"from_status": "PENDING",
"to_status": "PROCESSING",
"timestamp": "2026-10-13T18:40:23.497368",
"reason": null
},
{
"from_status": "PROCESSING",
"to_status": "FAILED",
"timestamp": "2026-10-13T18:40:23.497375",
"reason": "Provider rejected: invalid_institution_id"
}
],
"action": {
"action": "FAIL",
"reason": "Provider rejected: invalid_institution_id"
},
"url_cep": "",
"created_at": "2026-10-13T02:06:17.772297Z",
"modified_at": "2026-10-13T18:40:23.512117Z",
"paid_at": null
}{
"detail": "Invalid token."
}Autorización
Authorization Your public API key, with the word Token and a space in front of it. Example: Token 6534bc0a7e1f4d2b9c8e3a5f7b1d2c4e6f8a9b0c — that whole value is the header. Sending the key alone returns 401 'Authentication credentials were not provided'. In this playground you may paste just the key; the prefix is added for you.
In: header
Parámetros de consulta
Page number, starting at 1.
Items per page.
First creation date to include, YYYY-MM-DD.
Last creation date to include, YYYY-MM-DD. Must not precede start_date.
Cuerpo de la respuesta
application/json
application/json
application/json
curl -X GET "https://example.com/withdrawals/query/"{
"count": 1,
"results": [
{
"id": "ea6ac67d-b577-481a-9b99-3c3c275ae527",
"business_id": "69",
"status": "PAID_FULL",
"amount": 20,
"currency": "MXN",
"transfer_method": "SPEI",
"tracking_key": "2da0310418da4be18419",
"account_data": {
"nombre_beneficiario": "Ana Maria Gonzalez",
"cuenta_beneficiario": "012969100000000110",
"institucion_contraparte": "40012",
"tipo_cuenta_beneficiario": 40,
"rfc_curp_beneficiario": "GOAN850315AB2",
"concepto_pago": "Pago de comisiones",
"email": "ana.gonzalez@email.com"
},
"metadata": {
"order_reference": "ORD-001"
},
"status_changes": [
{
"from_status": "PENDING",
"to_status": "PROCESSING",
"timestamp": "2026-10-01T17:35:02.118402",
"reason": null
},
{
"from_status": "PROCESSING",
"to_status": "PAID_FULL",
"timestamp": "2026-10-01T17:37:41.902188",
"reason": "succeeded"
}
],
"url_cep": "https://www.banxico.org.mx/cep/",
"created_at": "2026-10-01T17:33:41.364685Z",
"modified_at": "2026-10-01T17:37:41.998211Z",
"paid_at": "2026-10-01T17:37:41.998227Z"
}
],
"search_mode": "date_range"
}{
"detail": "Invalid token."
}{
"error": "Failed to fetch withdrawals"
}Autorización
Authorization Your public API key, with the word Token and a space in front of it. Example: Token 6534bc0a7e1f4d2b9c8e3a5f7b1d2c4e6f8a9b0c — that whole value is the header. Sending the key alone returns 401 'Authentication credentials were not provided'. In this playground you may paste just the key; the prefix is added for you.
In: header
Cuerpo de la respuesta
application/json
application/json
application/json
curl -X GET "https://example.com/withdrawals/balance"{
"available": "32894.55",
"current_balance": "32894.55"
}{
"detail": "Invalid token."
}{
"detail": "Method \"POST\" not allowed."
}Autorización
Authorization Your public API key, with the word Token and a space in front of it. Example: Token 6534bc0a7e1f4d2b9c8e3a5f7b1d2c4e6f8a9b0c — that whole value is the header. Sending the key alone returns 401 'Authentication credentials were not provided'. In this playground you may paste just the key; the prefix is added for you.
In: header
Parámetros de consulta
Page number, starting at 1.
Items per page.
IANA time zone the dates are interpreted in.
First day to include, YYYY-MM-DD.
Last day to include, YYYY-MM-DD. Must be at least one day after start_date.
Cuerpo de la respuesta
application/json
application/json
curl -X GET "https://example.com/withdrawals/account_activity/query/"{
"results": [
{
"id": "9c1d7f32-5b0e-4a7d-9f2e-1c8a4b6d2e10",
"type": "withdrawal",
"amount": "20.00",
"business_id": "69",
"status": "succeeded",
"operation_date": "2026-10-01T17:37:41Z",
"created_at": "2026-10-01T17:37:48.668244Z",
"metadata": {
"tonder_withdrawal_id": "ea6ac67d-b577-481a-9b99-3c3c275ae527",
"beneficiary_account": "012969******0110",
"tracking_key": "2da0310418da4be18419",
"currency": "MXN"
},
"raw_json": {
"amount": 2000,
"currency": "MXN",
"status": "succeeded",
"tracking_key": "2da0310418da4be18419"
}
}
],
"next_token": null
}{
"detail": "Invalid token."
}Siguientes pasos
Casos de prueba — Retiros
Las cuentas de sandbox y cómo forzar cada estado terminal.
Validación de cuentas
Confirma de quién es la CLABE — nombre y RFC del banco — antes de dispersar.
Webhooks
La entrega, el payload y la confirmación del lado del servidor.
Resumen de API Direct
El endpoint unificado /process/ y la consulta de estado.
Reembolsos
Cómo reembolsar un pago con tarjeta, con las reglas que lo limitan: total, una vez, 29 días.
Retiros en Chile (CLP)
Envía pesos chilenos a una cuenta corriente o cuenta vista por transferencia bancaria: la petición, el beneficiario chileno, montos en pesos enteros, errores de validación y estados.
