Ir al contenido

Cuando algo falla

Lo que ves ¿Reintentas? Cómo
status: "submitted" No Espera el webhook. Ya está en curso
status: "unknown" NUNCA Se resuelve solo. Reintentar aquí es como se paga dos veces
status: "failed" + reason de datos Sí, tras corregir Corrige el beneficiario y pide otra cotización
status: "failed" + reason de red de pago Sí Otra cotización, sin cambiar nada más
502 upstream_error Sí Reintenta con la misma Idempotency-Key
503 no_route_available Sí, más tarde No hay red de pago ahora mismo para ese banco/instrumento
429 rate_limited Sí, más despacio Respeta Retry-After
4xx de validación No sin corregir El mismo cuerpo va a fallar igual

Qué hacemos mientras el pago está en duda:

  1. No se compensa nada. El asiento queda como está.

  2. Se consulta a la red de pago con nuestra referencia, con espera creciente.

  3. Se resuelve: pagó → settled; no reconoce la referencia tras varias consultas → se compensa y queda failed; devuelto → reversed.

  4. Te avisamos por webhook. No hace falta polling.

Para vigilarlo:

Ventana de terminal
curl -s "$BASE/v1/payments?status=unknown&limit=100" -H "x-api-key: $KEY"

El asiento ya está revertido y no se te ha cobrado nada (feeAmount: "0", compensated: true). Reintenta con otra cotización en cuanto arregles la causa, que está en reason:

reason De quién es el problema Reintento útil
beneficiary_missing_phone Tuyo: falta el móvil del beneficiario en pago móvil Tras cargar el phone
beneficiary_missing_account Tuyo: falta la cuenta Tras cargarla
beneficiary_mismatch Tuyo: nombre o cédula no coinciden con el titular Tras corregir. Ninguna red de pago lo aceptaría
invalid_destination_account Tuyo: la cuenta no existe o está mal Tras corregir
sender_required Tuyo: no había remitente Mandando el bloque sender
sender_phone_unsupported De la red de pago: ninguna disponible admitía el teléfono internacional del remitente Con un móvil venezolano del remitente, o más tarde
amount_below_minimum Del importe: por debajo del piso de la red de pago Subiendo el importe
amount_above_limit Del importe: por encima del techo Partiéndolo
bank_unreachable De la red de pago: no cubre ese banco Ya se intentó otro; revisa el catálogo del instrumento
payout_insufficient_balance De la cuenta que dispersa: sin saldo para el pago y la comisión Tras recargarla, o más tarde
payout_balance_unavailable De la red de pago: no se pudo leer el saldo, no se envió nada Sí, en unos segundos
no_route De la combinación: no hay red de pago disponible Prueba el otro instrumento

Si el instrumento que pediste no está disponible y methodPolicy es preferred (por defecto), el pago sale por el otro:

{ "status": "submitted", "method": "transferencia",
"methodRequested": "pago_movil", "methodChanged": true }

El estado sigue siendo submitted: el cambio de canal ya ocurrió, pero el envío todavía está liquidando. Con methodPolicy: "strict" la dispersión falla en vez de cambiar de canal.

Días después, el banco puede devolver una transferencia (cuenta cerrada, datos incorrectos). El evento se verifica y se deduplica, se revierte el asiento —el pago pasa a reversed y los fondos vuelven a tu saldo— y recibes payment.reversed con el motivo que reportó el banco. Lo que te toca es avisar a tu usuario.

Reintentamos con espera creciente (5 s → 6 h, 12 intentos). Al agotarlos el evento pasa a tu cola de fallidos, consultable y reentregable.

Ventana de terminal
curl -s "$BASE/v1/events?status=dead" -H "x-api-key: $KEY"
curl -s -X POST "$BASE/v1/events/retry-dead" -H "x-api-key: $KEY"

Ver webhooks.

Cada caso se provoca en el entorno de pruebas: mode: "reject" con method para el cambio de canal, mode: "timeout_after_submit" para el pago en duda, /sandbox/bank/payout-settled y /sandbox/bank/payout-returned para la confirmación tardía y la devolución, y /sandbox/webhooks/failing para tus reintentos.

Ventana de terminal
curl -s -X POST $BASE/sandbox/chaos -H 'content-type: application/json' \
-d '{"mode":"timeout_after_submit"}'