Simulador de PSE
pse-sandbox imita el rail PSE de Akua porque Akua no ofrece un ambiente de pruebas que llegue hasta un banco simulado. No mueve dinero, no llama a Akua ni a bancos reales y no es un sandbox oficial.
Qué simula
| Capacidad | Comportamiento |
|---|---|
| Token | POST /oauth/token con credenciales locales. |
| Bancos | GET /api/banks?country=COL&rail_id=PSE: catálogo de prueba (incluye el banco 1007 que el motor puede forzar). |
| Intención | POST /v1/payments/intents → 202 con payment_id, rail.payment_link y transaction. Con Idempotency-Key: misma respuesta para el mismo cuerpo, 409 si cambia. |
| Consultas | GET /v1/payments/{id} y GET /v1/transactions/{id}. |
| Comercios | POST/PUT/GET /v1/merchants (y alta automática en la primera intención). |
| Banco simulado | Página con el aviso "SIMULACIÓN — SIN DINERO REAL" y las decisiones de abajo. |
| Webhooks | Registro (/v1/webhooks) y entrega firmada (akua-wh-*, HMAC-SHA256) con reintentos persistentes. |
Decisiones del banco simulado
| Botón | Resultado | Evento | status_detail |
|---|---|---|---|
| Aprobar | Aprobado | payment.purchase.succeeded | SUCCESS |
| Rechazar | Rechazado | payment.purchase.rejected | USER_DECLINED |
| Fondos insuficientes | Rechazado | payment.purchase.rejected | INSUFFICIENT_FUNDS (valor local) |
| Proveedor no disponible | Fallido | payment.purchase.failed | PROVIDER_UNAVAILABLE |
| Volver sin resolver | Sigue pendiente | — | PENDING_CUSTOMER |
| (sin acción) | Vence a los 30 min | payment.purchase.rejected | EXPIRED (valor local) |
Un pago nace con un evento payment.purchase.pending. La sesión del banco dura 15 min: pasada esa hora el enlace responde 410 con una página explicativa y el pago no se cancela. El vencimiento del pago (por defecto 30 min, configurable; 0 lo desactiva) lo cierra como rechazado con motivo EXPIRED.
Diferencias con Akua
- El token, los clientes, los comercios y el catálogo son locales.
- El payload del webhook es el mínimo de la guía de Akua (
type,data.payment_id,data.transaction_id); el motivo de un rechazo se obtiene consultandoGET /v1/transactions/{id}. INSUFFICIENT_FUNDSyEXPIREDson valores del simulador, no documentados por Akua para PSE.- La proyección del estado agregado del pago es provisional.
- No implementa tarjetas (
/v1/links).
El detalle contractual (qué está documentado, qué es decisión local y qué falta confirmar) vive en pse-sandbox/docs/contract-matrix.md y known-differences.md del repositorio.