Ir al contenido

Estados de un pago

Estado Qué significa Qué haces
submitted El riel aceptó el envío y está liquidando. Es el desenlace normal No reintentar. Esperar el webhook
settled Liquidado: el beneficiario tiene su dinero Nada
failed Ningún riel lo aceptó. El asiento ya se revirtió: no se te cobra nada Corregir y reintentar con otra cotización
unknown El riel no confirmó: puede haber pagado o no NUNCA reintentar. Se resuelve solo
reversed El banco devolvió un pago ya liquidado. Los fondos vuelven a tu saldo Avisar a tu usuario

Estados intermedios que aparecen en la historia y no son desenlaces: created, pending, returned.

┌──────────► settled ──────► reversed
│ ▲ ▲
created ─► submitted ─────────► │ │
│ │ │ │
│ └──► unknown ──┤ │
│ │ │ │
└─────────┴──► failed returned
(terminal) │
└──► reversed

Transiciones permitidas, tal como las valida el servidor:

created → pending · submitted · failed
pending → submitted · settled · failed
submitted → settled · failed · unknown · returned
unknown → settled · failed · returned
settled → returned · reversed
returned → reversed
failed → (terminal)
reversed → (terminal)

Un evento fuera de orden del banco no puede resucitar un pago fallido ni volver a liquidar uno ya liquidado: una transición prohibida da 409 invalid_state_transition, con meta diciendo desde dónde, hacia dónde y qué se permitía.

submitted ya trae el id del pago. El desenlace llega por webhook (payment.settled o payment.failed) una sola vez.

Un pago unknown responde 200, no un error. Mientras tanto no se compensa nada, se reconsulta al riel con nuestra referencia y se resuelve según lo que diga; te avisamos por webhook. El detalle: cuando algo falla.

El asiento contable ya está revertido: compensated: true y fee_amount: "0". La causa está en reason (en la respuesta del POST) y en status_reason (en el pago). Ver cuando algo falla.

GET /v1/payments/{id} devuelve events: cada transición, con su actor y su reason.

Un pago que quedó en duda y se resolvió
"events": [
{ "to_status": "submitted", "reason": "ledger_committed", "actor": "api" },
{ "to_status": "unknown", "reason": "provider_timeout", "actor": "api" },
{ "to_status": "settled", "reason": "resolved_by_reaper", "actor": "reaper" }
]
actor Quién movió el pago
api Tu propia llamada
provider_event El riel nos avisó
reaper Nuestro proceso de resolución, reconsultando al riel
system Mantenimiento interno

Motivos habituales: ledger_committed, rail_accepted, rail_accepted_async, resolved_by_reaper, rail_failed, rail_returned, provider_reported_failure.