Transacción a dos tiempos
Un pago en SPIDI no es un solo evento: es un débito y, después, una acreditación. Entender esto evita el error de integración más común.
Los dos tiempos
Leg 1 — Débito
El pagador paga y se debita el origen. La sesión pasa de pending a uno de:
paid— el pago salió bien.failed— el pago fue rechazado (solo aplica al Botón).expired— la sesión venció sin pagarse.
Se emite el webhook payment_session.paid.
Leg 2 — Acreditación
El dinero se acredita al beneficiario. Aquí se aplica la comisión. Se emite el webhook payment_session.accredited.
Si tu acuerdo tiene split, el leg 2 se reparte entre varios receptores — y tu mismo webhook_url recibe varias llamadas para esa única sesión, no una. → Split.
El detalle que confunde a todo integrador
status nunca refleja el leg 2Tras paid, el status de la sesión se queda en paid — la acreditación no lo cambia. El leg 2 viaja solo por webhook (payment_session.accredited).
Si tu integración solo consulta GET status esperando un accredited, nunca llegará. Para saber que el dinero se acreditó, escucha el webhook.
Cómo se ve en el tiempo
crear sesión
│ status: pending
▼
LEG 1 debita ──────────► status: paid + webhook payment_session.paid
│
▼
LEG 2 acredita ─────────► status: paid (igual) + webhook payment_session.accredited
(aquí se aplica la comisión)
Por qué importa
- Confirmar el pago (leg 1): consulta
GET statuso escuchapayment_session.paid. - Confirmar que te llegó el dinero (leg 2): escucha
payment_session.accredited— no lo verás en elstatus.
Pruébalo
En el simulador puedes forzar cada tiempo por separado y ver ambos webhooks:
# leg 1 (débito)
curl -X POST https://sim-productos.abiertolab.com/control/sessions/<id>/outcome \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" -d '{"leg":1,"outcome":"paid"}'
# leg 2 (acreditación)
curl -X POST https://sim-productos.abiertolab.com/control/sessions/<id>/outcome \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" -d '{"leg":2,"outcome":"accredited"}'