Ciclo de vida del pago
Los estados normalizados y sus transiciones, iguales para todos los PSPs.
Cauril expone una sola máquina de estados para los pagos. No importa si por debajo está Stripe o Mercado Pago: vos siempre ves estos estados.
Estados
| Estado | Significado |
|---|---|
created | El pago se registró; aún no hay resultado del PSP. |
pending | En curso del lado del PSP. |
requires_action | Necesita acción del cliente (ej. 3D Secure). Mirá next_action. |
processing | El PSP lo está procesando; el resultado final llegará por webhook. |
succeeded | Cobrado con éxito. |
failed | Rechazado o fallido. Mirá failure.code. |
canceled | Cancelado antes de completarse. |
partially_refunded | Reembolsado en parte. |
refunded | Reembolsado en su totalidad. |
Transiciones
| Desde | Puede pasar a |
|---|---|
created | pending, requires_action, processing |
pending | requires_action, processing, succeeded, failed, canceled |
requires_action | processing, failed |
processing | succeeded, failed, canceled |
succeeded | partially_refunded, refunded |
partially_refunded | refunded |
failed · canceled · refunded | terminales, no transicionan |
Forward-only: nunca retrocede
Las transiciones son solo hacia adelante. Un estado terminal (succeeded, failed, canceled, refunded) no vuelve atrás. Esto importa porque los webhooks del PSP pueden llegar fuera de orden o duplicados: un evento processing que llega tarde no va a pisar un pago ya succeeded. Podés confiar en que el estado solo progresa.
payment.succeeded una vez, sin asumir el orden de llegada de los eventos.requires_action
Si un pago queda en requires_action, el objeto incluye next_action con la URL a la que redirigir al cliente (ej. autenticación 3DS). Tras completarla, el PSP notifica por webhook y el pago avanza a succeeded o failed.
{
"status": "requires_action",
"next_action": { "type": "redirect", "url": "https://..." }
}