Colombia — Descripción general
Colombia (CO) soporta dos proveedores de pago, accesibles bajo el prefijo /v1/co/*:
- Nequi — cobro por notificación push al celular, cobro con QR y dispersión a celulares Nequi.
- Bre-B — sistema de pagos inmediatos interoperable de Colombia: cobro con QR, cobro por llave efímera, dispersión a llaves Bre-B y validación de llaves.
El proveedor se elige por la ruta: /v1/co/payin/... y /v1/co/payout/... → Nequi; /v1/co/breb/... → Bre-B.
API key
Sección titulada «API key»La autenticación hacia nuestra API usa 4 headers firmados con ECDSA-SHA256 (secp256k1). Ver Firma ECDSA.
La API key debe crearse con region: "CO". Una key de CO solo firma paths /v1/co/*.
| Header | Descripción |
|---|---|
x-client-id | ID de la API Key del cliente (región CO) |
x-timestamp | ISO 8601 actual (±5 min) |
x-nonce | String único por request |
x-signature | Firma ECDSA-SHA256 en Base64 |
x-content-sha256 | SHA-256 del body en hex minúscula |
Formato de respuestas
Sección titulada «Formato de respuestas»Todas las respuestas viajan envueltas: { "success": true, "data": { … }, "requestId": "…" } en éxito, y { "success": false, "error": { "code", "message", "details" }, "requestId": "…" } en error. Los campos de negocio están dentro de data.
En los ejemplos de estas páginas se muestra solo el contenido de data. Ver Códigos HTTP y errores para el envoltorio completo y la tabla de error.code.
Índice de endpoints
Sección titulada «Índice de endpoints»Todos los endpoints usan autenticación por firma. Montos siempre en pesos COP enteros.
Generales (ambos proveedores)
Sección titulada «Generales (ambos proveedores)»| Método | Path | Descripción |
|---|---|---|
GET | /v1/co/balance | Balance regional CO con desglose por proveedor |
GET | /v1/co/transactions | Lista de transacciones (Nequi + Bre-B) para conciliación |
| Método | Path | Descripción |
|---|---|---|
POST | /v1/co/payin/push | Cobro por notificación push |
GET | /v1/co/payin/push/{txId} | Estado de un cobro push |
POST | /v1/co/payin/push/{txId}/cancel | Cancelar un cobro push pendiente |
POST | /v1/co/payin/qr | Cobro con código QR |
GET | /v1/co/payin/qr/{txId} | Estado de un cobro QR |
POST | /v1/co/payout/disburse | Dispersión a celular Nequi |
GET | /v1/co/payout/{externalId} | Estado de una dispersión |
| Método | Path | Descripción |
|---|---|---|
POST | /v1/co/breb/payin/qr | Crear QR de cobro dinámico (con monto) |
GET | /v1/co/breb/payin/qr/{txId} | Estado del cobro (alias: /v1/co/breb/payin/{txId}) |
GET | /v1/co/breb/payin/qr/{txId}/detail | Detalle del recurso QR en la red |
POST | /v1/co/breb/payin/qr/decode | Decodificar una cadena EMVCo de QR |
DELETE | /v1/co/breb/payin/qr/{txId} | Cancelar/eliminar un QR |
POST | /v1/co/breb/payin/key | Crear cobro por llave efímera (sin QR) |
GET | /v1/co/breb/payin/key/{txId} | Estado de un cobro por llave |
DELETE | /v1/co/breb/payin/key/{txId} | Cancelar un cobro por llave |
POST | /v1/co/breb/validate-key | Validar una llave sin exponer PII |
POST | /v1/co/breb/payout | Dispersión a una llave Bre-B |
GET | /v1/co/breb/payout/{externalId} | Estado de una dispersión |
Sandbox vs Producción
Sección titulada «Sandbox vs Producción»En sandbox (configuración por defecto) el gateway simula el desenlace automáticamente: al crear la transacción, esta pasa a COMPLETED de inmediato, el balance se mueve igual que en producción y recibes el webhook correspondiente con el campo extra "sandbox": true. La respuesta del POST de creación sigue devolviendo el estado inicial (PENDING / PROCESSING).
Nequi vs Bre-B
Sección titulada «Nequi vs Bre-B»| Aspecto | Nequi | Bre-B |
|---|---|---|
| Pay-In | Push (al celular) + QR | QR dinámico + cobro por llave efímera |
| Pay-Out | Dispersión por celular | Dispersión a una llave |
| Llaves | — | ID, PHONE, EMAIL, ALPHA, BCODE |
| Monto máximo | Según límites de tu cuenta | Según límites de tu cuenta |
| Reversos | Gestionados por Rivopay a solicitud (fuera de la API) | No disponible |
Estados de transacción
Sección titulada «Estados de transacción»| Estado | Significado |
|---|---|
PENDING | Creada, esperando aprobación / pago |
PROCESSING | Dispersión / reverso en curso |
COMPLETED | Finalizada con éxito (terminal — mueve el balance) |
FAILED | Error definitivo (terminal) |
CANCELLED | Cancelada por ti (push cancelado, QR eliminado) |
EXPIRED | Venció sin pago (QR / push no aprobado a tiempo) |
Cómo se cierra una transacción
Sección titulada «Cómo se cierra una transacción»No dependemos del webhook del proveedor. Una transacción en vuelo se cierra por cualquiera de estas tres vías, la que ocurra primero:
- Webhook del proveedor — la vía normal.
- Tu
GETde estado — si la transacción sigue abierta, la consulta pregunta al proveedor en vivo y, si detecta el desenlace, cierra la transacción, mueve el ledger y dispara tu webhook. - Cron interno — revisa las transacciones en vuelo cada minuto y hace lo mismo.
Por eso tu webhook se dispara igual aunque el proveedor no nos notifique, y una escritura condicional garantiza que salga una sola vez por transacción.
Vencimiento
Sección titulada «Vencimiento»| Cobro | Cuándo pasa a EXPIRED |
|---|---|
| Nequi push | A los 45 minutos por defecto, o a los expirationMinutes que pidas (1–60); lo cancelamos en Nequi y enviamos payin.expired |
| Nequi QR | A los 45 minutos por defecto, o a los expirationMinutes que pidas (1–60) |
| Bre-B (QR y llave) | A los 15 minutos, y se borran el QR y la llave efímera en la red |