Flujo completo: pago, webhook y reembolso
Ejemplo de punta a punta con los requests y responses de cada paso: crear un pago por transferencia, recibir el webhook, confirmar el pago y reembolsarlo.
| Ambiente | Base URL |
|---|---|
| Sandbox | https://sandbox-api.talo.com.ar |
| Producción | https://api.talo.com.ar |
Todos los ejemplos usan sandbox. Para producción, reemplazá la base URL.
Placeholders usados:
<USER_ID>: ID de tu cuenta Talo.<TOKEN>: token de acceso obtenido en el paso 0.<PAYMENT_ID>: ID del pago devuelto en el paso 1 (en estos ejemplos,VAR-<USER_ID>-DEMO-1792676354).
Resumen del flujo
| Paso | Acción | Endpoint |
|---|---|---|
| 0 | Obtener token | POST /users/{user_id}/tokens |
| 1 | Crear el pago (devuelve CVU/alias) | POST /payments/ |
| 2 | El comprador transfiere (en sandbox, se simula) | POST /cvu/{cvu}/faucet |
| 3 | Talo notifica a tu webhook_url | POST a tu servidor |
| 4 | Consultar el pago y confirmar el estado | GET /payments/{payment_id} |
| 5 | Crear un reembolso (opcional) | POST /payments/{payment_id}/refunds |
| 6 | Consultar el resultado del reembolso | GET /payments/{payment_id} |
Paso 0 – Obtener token de acceso
Las credenciales (client_id / client_secret) se obtienen desde el panel de Talo, en la sección Conexiones. Más detalle en Autenticación.
Request
POST https://sandbox-api.talo.com.ar/users/<USER_ID>/tokens
Content-Type: application/json{
"client_id": "<CLIENT_ID>",
"client_secret": "<CLIENT_SECRET>"
}Response 200
{
"message": "ok",
"error": false,
"data": {
"token": "<TOKEN>"
}
}Usá el token en el header Authorization: Bearer <TOKEN> en los endpoints que lo requieren.
Paso 1 – Crear el pago
Este endpoint no requiere Authorization. El comercio se identifica por el user_id del body. Ver todos los campos en Payments API.
Request
POST https://sandbox-api.talo.com.ar/payments/
Content-Type: application/json{
"user_id": "<USER_ID>",
"price": { "amount": 15000, "currency": "ARS" },
"payment_options": ["transfer"],
"external_id": "DEMO-1792676354",
"motive": "Orden de prueba",
"webhook_url": "https://tu-sitio.com/webhooks/talo",
"redirect_url": "https://tu-sitio.com/checkout/gracias",
"client_data": {
"first_name": "Juan",
"last_name": "Pérez",
"email": "juan@example.com",
"dni": "12345678"
}
}| Campo | Requerido | Descripción |
|---|---|---|
user_id | Sí | ID de tu cuenta Talo |
price.amount | Sí | Monto del pago |
price.currency | Sí | "ARS" |
payment_options | Sí | ["transfer"] |
external_id | No | ID de la orden en tu sistema (viene en el webhook) |
webhook_url | No | URL donde Talo notifica los cambios de estado del pago |
redirect_url | No | URL a la que se redirige al comprador al terminar el pago |
motive | No | Motivo del pago |
client_data | No | Datos del comprador |
store | No | Tienda a la que se asocia el pago. Ver Asociar el pago a una tienda |
Response 200
{
"message": "ok",
"error": false,
"code": 200,
"data": {
"id": "VAR-<USER_ID>-DEMO-1792676354",
"user_id": "<USER_ID>",
"external_id": "DEMO-1792676354",
"payment_status": "PENDING",
"price": { "amount": 15000, "currency": "ARS" },
"quotes": [
{
"currency": "ARS",
"network": "MOCK_NETWORK",
"amount": "15000",
"address": "0000735981203251372981",
"alias": "another.24982.talo"
}
],
"payment_url": "https://sandbox.talo.com.ar/payments/VAR-<USER_ID>-DEMO-1792676354",
"payment_options": ["transfer"],
"motive": "Orden de prueba",
"transfer_tolerance": 20,
"automatic_cancellation": true,
"creation_timestamp": "2026-10-22T13:42:18.565Z",
"last_modified_timestamp": "2026-10-22T13:42:18.565Z",
"expiration_timestamp": "2026-10-22T14:42:18.565Z",
"is_deleted": false
}
}Mostrale al comprador quotes[0].address (CVU) o quotes[0].alias, o redirigilo a payment_url. Guardá data.id: es el <PAYMENT_ID>.
network identifica la red que procesa la transferencia. Su valor puede variar; no lo uses para lógica de negocio.
Paso 2 – Simular la transferencia (solo sandbox)
En producción este paso lo hace el comprador, transfiriendo desde su banco o billetera.
Request
POST https://sandbox-api.talo.com.ar/cvu/0000735981203251372981/faucet
Authorization: Bearer <TOKEN>
Content-Type: application/json{ "amount": 15000 }Response 200
{
"message": "ok",
"error": false,
"code": 200,
"data": {
"cvu": "0000735981203251372981",
"amount": 15000,
"user_id": "<USER_ID>"
}
}La acreditación es asíncrona: el pago pasa a SUCCESS unos segundos después de la transferencia.
Paso 3 – Webhook de actualización del pago
Cuando cambia el estado del pago, Talo envía un POST a la webhook_url indicada al crear el pago. Más detalle en Webhooks.
Request que recibe tu servidor
POST https://tu-sitio.com/webhooks/talo
Content-Type: application/json{
"message": "Pago actualizado",
"externalId": "DEMO-1792676354",
"paymentId": "VAR-<USER_ID>-DEMO-1792676354"
}El payload es mínimo a propósito: no incluye el estado. Usá paymentId para consultar el pago (paso 4) y tomar el estado desde ahí.
- Respondé
200rápido. Si tu endpoint no responde200/201(o hay timeout), Talo reintenta el envío. - No dependas del texto de
message. UsápaymentId/externalId. - El procesamiento debe ser idempotente: podés recibir más de una notificación para el mismo pago.
Paso 4 – Consultar el pago
Request
GET https://sandbox-api.talo.com.ar/payments/VAR-<USER_ID>-DEMO-1792676354
Authorization: Bearer <TOKEN>Response 200 (pago acreditado)
{
"message": "ok",
"error": false,
"code": 200,
"data": {
"id": "VAR-<USER_ID>-DEMO-1792676354",
"user_id": "<USER_ID>",
"external_id": "DEMO-1792676354",
"payment_status": "SUCCESS",
"price": { "amount": 15000, "currency": "ARS" },
"quotes": [
{
"address": "0000735981203251372981",
"alias": "another.24982.talo",
"amount": "15000",
"currency": "ARS",
"network": "MOCK_NETWORK"
}
],
"payment_url": "https://sandbox.talo.com.ar/payments/VAR-<USER_ID>-DEMO-1792676354",
"payment_options": ["transfer"],
"motive": "Orden de prueba",
"transfer_tolerance": 20,
"automatic_cancellation": true,
"transaction_fields": {
"amount": "15000",
"amountReadable": "15000",
"currency": "ARS",
"network": "MOCK_NETWORK",
"commission_amount": "145.2",
"credited_amount": "14763.93",
"refunded_amount": "0",
"total_paid": { "amount": "15000", "currency": "ARS" },
"net_paid": { "amount": "15000", "currency": "ARS" }
},
"transactions": [
{
"transaction_id": "3f8a2c1e-7b4d-4e9a-9c2f-1a6b5d8e0f47",
"transactionType": "INBOUND",
"transaction_status": "PROCESSED",
"amount": "15000",
"currency": "ARS",
"network": "MOCK_NETWORK",
"address": "0000735981203251372981",
"address_alias": "another.24982.talo",
"sender_address": "3220000039812108032662",
"commission": 0.968,
"commission_amount": "145.20",
"commission_tax_amount": "0.87",
"commission_taxes": [
{ "tax_type": "DEBIT", "tax_rate": 0.6, "tax_amount": 0.8712 }
],
"tax_amount": "90.00",
"taxes": [{ "tax_type": "CREDIT", "tax_rate": 0.6, "tax_amount": 90 }],
"credited_amount": "14763.93",
"transaction_data": {
"PROCESSED": {
"amount": 15000,
"netAmount": 14850,
"currency": "ARS",
"sender": "3220000039812108032662",
"senderCuit": "23844291385",
"senderTitular": "Laura Pérez",
"recipient": "0000735981203251372981",
"trxId": "3f8a2c1e-7b4d-4e9a-9c2f-1a6b5d8e0f47",
"coelsaId": "BfvboFRpXrZ6",
"type": "CASH_IN",
"operationType": "CASH_IN",
"status": "PROCESSED",
"createdAt": "2026-10-22T13:42:38.774Z"
}
},
"creation_timestamp": "2026-10-22T13:42:50.250Z",
"last_modified_timestamp": "2026-10-22T13:42:50.250Z"
}
],
"creation_timestamp": "2026-10-22T13:42:18.565Z",
"last_modified_timestamp": "2026-10-22T13:43:01.825Z",
"expiration_timestamp": "2026-10-22T14:42:18.565Z",
"is_deleted": false
}
}Estados del pago (payment_status)
| Estado | Descripción |
|---|---|
PENDING | Esperando la transferencia |
SUCCESS | Se acreditó el monto esperado |
OVERPAID | Se recibió más de lo solicitado |
UNDERPAID | Se recibió menos de lo solicitado |
EXPIRED | El pago venció sin acreditarse |
transactions[] lista cada transferencia recibida (y, si hay reembolsos, las salientes). transaction_fields resume los totales: pagado, comisión, acreditado y reembolsado.
Paso 5 – Crear un reembolso
Se puede reembolsar el total o una parte de un pago acreditado. Referencia completa en Devoluciones.
El reembolso es asíncrono: el POST lo deja en PENDING y el resultado final se consulta con GET /payments/{payment_id} (paso 6).
Request – reembolso parcial
POST https://sandbox-api.talo.com.ar/payments/VAR-<USER_ID>-DEMO-1792676354/refunds
Authorization: Bearer <TOKEN>
Content-Type: application/json{
"refund_type": "PARTIAL",
"amount": "5000",
"currency": "ARS"
}Request – reembolso total
POST https://sandbox-api.talo.com.ar/payments/VAR-<USER_ID>-DEMO-1792676354/refunds
Authorization: Bearer <TOKEN>
Content-Type: application/json{
"refund_type": "FULL"
}| Campo | Requerido | Descripción |
|---|---|---|
refund_type | Sí | "FULL" o "PARTIAL" |
amount | Solo en PARTIAL | Monto a reembolsar, como string |
currency | Solo en PARTIAL | "ARS" |
Response 200
La respuesta devuelve el pago completo. El reembolso recién creado es el último elemento de data.refunds[]. A continuación, se muestran solo los campos relevantes; el resto es igual al paso 4.
{
"message": "ok",
"error": false,
"code": 200,
"data": {
"id": "VAR-<USER_ID>-DEMO-1792676354",
"external_id": "DEMO-1792676354",
"payment_status": "SUCCESS",
"transaction_fields": {
"amount": "15000",
"currency": "ARS",
"refunded_amount": "0",
"total_paid": { "amount": "15000", "currency": "ARS" },
"net_paid": { "amount": "15000", "currency": "ARS" }
},
"refunds": [
{
"refund_id": "693ffe12-21f4-4b2f-999f-6287a596cb23",
"refund_type": "PARTIAL",
"refund_status": "PENDING",
"amount": "5000",
"amount_with_tax": "5000",
"tax_amount": "0",
"currency": "ARS",
"blame": {
"mail": "<EMAIL_DEL_USUARIO>",
"team_id": "<TEAM_ID>"
},
"transaction_progress": {
"3f8a2c1e-7b4d-4e9a-9c2f-1a6b5d8e0f47": { "transaction_status": "PENDING" }
},
"transaction_ids": [],
"creation_timestamp": "2026-10-22T13:43:34.151Z"
}
],
"last_modified_timestamp": "2026-10-22T13:43:34.250Z"
}
}Notas:
- No se puede crear un reembolso nuevo mientras haya otro en
PENDINGsobre el mismo pago. blamelo completa Talo con el usuario/equipo autenticado; no hace falta enviarlo.transaction_progressindica el avance del reembolso por cada transferencia entrante del pago.
Paso 6 – Consultar el resultado del reembolso
Request
GET https://sandbox-api.talo.com.ar/payments/VAR-<USER_ID>-DEMO-1792676354
Authorization: Bearer <TOKEN>Leé data.refunds[] (el último elemento corresponde al reembolso más reciente) y su refund_status.
Estados del reembolso (refund_status)
| Estado | Descripción |
|---|---|
PENDING | El reembolso se está procesando |
SUCCESS | El reembolso se completó |
FAILED | El reembolso falló; no se movieron fondos |
Ejemplo – reembolso completado (solo campos relevantes)
{
"message": "ok",
"error": false,
"code": 200,
"data": {
"id": "VAR-<USER_ID>-DEMO-1792676354",
"payment_status": "SUCCESS",
"transaction_fields": {
"amount": "15000",
"currency": "ARS",
"refunded_amount": "5000",
"total_paid": { "amount": "15000", "currency": "ARS" }
},
"transactions": [
{
"transaction_id": "3f8a2c1e-7b4d-4e9a-9c2f-1a6b5d8e0f47",
"transactionType": "INBOUND",
"transaction_status": "PROCESSED",
"amount": "15000"
},
{
"transaction_id": "b71e4d92-5c3a-4f18-8e6d-2a9c0f3b7e15",
"transactionType": "OUTBOUND",
"transaction_status": "PROCESSED",
"amount": "-5000",
"is_refund": true,
"inbound_transaction_id": "3f8a2c1e-7b4d-4e9a-9c2f-1a6b5d8e0f47"
}
],
"refunds": [
{
"refund_id": "693ffe12-21f4-4b2f-999f-6287a596cb23",
"refund_type": "PARTIAL",
"refund_status": "SUCCESS",
"amount": "5000",
"currency": "ARS",
"transaction_progress": {
"3f8a2c1e-7b4d-4e9a-9c2f-1a6b5d8e0f47": {
"transaction_status": "PROCESSED",
"transaction_id": "b71e4d92-5c3a-4f18-8e6d-2a9c0f3b7e15"
}
},
"transaction_ids": ["b71e4d92-5c3a-4f18-8e6d-2a9c0f3b7e15"],
"creation_timestamp": "2026-10-22T13:43:34.151Z"
}
]
}
}Ejemplo – reembolso rechazado (solo refunds[])
"refunds": [
{
"refund_id": "693ffe12-21f4-4b2f-999f-6287a596cb23",
"refund_type": "PARTIAL",
"refund_status": "FAILED",
"amount": "5000",
"currency": "ARS",
"transaction_progress": {
"3f8a2c1e-7b4d-4e9a-9c2f-1a6b5d8e0f47": { "transaction_status": "REJECTED" }
},
"transaction_ids": [],
"creation_timestamp": "2026-10-22T13:43:34.151Z"
}
]Si el reembolso falla, el pago no cambia (refunded_amount sigue en "0") y se puede volver a intentar.
Errores
Todos los errores usan el mismo formato:
{
"error": true,
"message": "payment.not.found",
"code": 404
}| HTTP | message (ejemplos) | Cuándo |
|---|---|---|
401/403 | – | Token ausente, vencido o sin permisos |
404 | payment.not.found | El pago no existe o no pertenece a tu cuenta |
409 | refund.already.pending | Ya hay un reembolso PENDING para ese pago |
409 | payment.not.refundable, payment.no.inbound.transactions | El pago no tiene fondos acreditados para reembolsar |
409 | refund.amount.exceeds.payment.amount | El monto pedido supera lo disponible para reembolsar |
409 | refund.amount.must.be.positive | Monto <= 0 |
422 | – | Body inválido (por ejemplo, falta amount en un reembolso PARTIAL) |
5xx | – | Error interno; reintentá más tarde |