Colombia — recetas de integración
Los rails cableados en el endpoint /payments de pagos alternativos para Colombia son Nequi (nequi) y GlobalPay PSE (globalPay-PSE).
Setup (hazlo una sola vez)
Todas las recetas asumen las variables de abajo. Configúralas en tu shell antes de ejecutar cualquier curl. El host (sb-mw.migopayments.com) y el path (/api/v1/integrations/...) son el sandbox público alcanzable por integradores externos. Las rutas de Pagos Alternativos aceptan el token de comercio de larga duración de 64 caracteres como token Bearer — ve Autenticación → Formato del header por endpoint.
export MIGO_BASE="https://sb-mw.migopayments.com"
export MIGO_CLIENT="<your-client-slug>"
export MIGO_TOKEN="<your-64-char-merchant-token>" # 64 hex chars
export MIGO_USER_ID="+57300000000"
export UID=$(
curl -s -X POST "$MIGO_BASE/api/v1/integrations/transactions" \
-H "Authorization: Bearer $MIGO_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"amount\": 50000,
\"channel\": \"web\",
\"client\": \"$MIGO_CLIENT\",
\"userId\": \"$MIGO_USER_ID\",
\"customKeys\": { \"orderId\": \"recipe-test\" }
}" | jq -r '.data.uid'
)
Inspecciona los paymentMethods retornados para confirmar qué rails tiene habilitados tu cliente (resueltos en runtime desde clientConfig.processors).
Nequi (nequi) — directo
País: Colombia · Tipo: Push notification a la app Nequi del cliente ·
payment-intentsprevio: Opcional (retorna fixture de teléfono en sandbox) · Payload de respuesta:payButton.
Paso A (opcional) — Obtener datos del fixture
curl -X POST "$MIGO_BASE/api/v1/integrations/transactions/$UID/payment-intents" \
-H "Authorization: Bearer $MIGO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "processor": "nequi" }'
El handler de payment-intents trata de forma especial a nequi; los integradores en producción típicamente recolectan el teléfono del usuario.
Paso B — Procesar el pago
curl -X POST "$MIGO_BASE/api/v1/integrations/transactions/$UID/payments" \
-H "Authorization: Bearer $MIGO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "processor": "nequi", "data": { "phoneNumber": "3001234567" } }'
Respuesta esperada — data.data lleva el paymentRequest.message de Nequi:
{
"success": true,
"message": "Success",
"data": {
"transaction_id": "…",
"type": "payButton",
"data": "<paymentRequest.message>",
"cancelAt": null
}
}
payButton significa que el cliente está autorizando dentro de su app Nequi. No hay un endpoint público GET-by-uid en esta superficie para hacer polling — depende del callback del comercio configurado en clientConfig.callback para el estado (ve Merchant Generic Callback).
Reembolsos: revert de nequi vía POST $MIGO_BASE/revert con body {"transactionUid":"$UID","processor":"nequi"} (esquema JWT-Bearer, separado de esta superficie de token de comercio).
Checklist de hecho
-
paymentMethodsconteníanequi. - Respuesta
payButtonleída desdedata.data. - Callback del comercio recibido para el teléfono de prueba.
GlobalPay PSE (globalPay-PSE)
País: Colombia · Tipo: PSE — el cliente es redirigido al portal en línea de su banco ·
payment-intentsprevio: Requerido (retorna la lista de bancos) · Payload de respuesta:html.
Paso A — Obtener la lista de bancos
curl -X POST "$MIGO_BASE/api/v1/integrations/transactions/$UID/payment-intents" \
-H "Authorization: Bearer $MIGO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "processor": "globalPay-PSE" }'
Respuesta — banks, fisTypes, userTypes y accountTypes se pueblan todos desde la configuración del procesador (processorCfg.extras); los contenidos de abajo son solo ilustrativos:
{
"data": {
"banks": [{ "key": "1007", "value": "Bancolombia" }, …],
"fisTypes": [{ "key": "0", "value": "Natural" }, { "key": "1", "value": "Jurídica" }],
"userTypes": [{ "key": "CC", "value": "Cédula de Ciudadanía" }, …],
"accountTypes": [{ "key": "…", "value": "…" }, …]
}
}
Renderiza selects para bank, fisType, userType y recolecta userName, email, fiscalNumber, installments.
Paso B — Procesar el pago
curl -X POST "$MIGO_BASE/api/v1/integrations/transactions/$UID/payments" \
-H "Authorization: Bearer $MIGO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"processor": "globalPay-PSE",
"data": {
"bank": { "key": "1007", "value": "Bancolombia" },
"fisType": { "key": "0", "value": "Natural" },
"userType": { "key": "CC", "value": "Cédula de Ciudadanía" },
"userName": "Test User",
"email": "test@example.com",
"fiscalNumber": "1020304050",
"installments": 1
}
}'
Respuesta — el formulario de auto-submit está en data.html (no data.value):
{
"success": true,
"message": "success",
"data": {
"uid": "trx_…",
"type": "html",
"html": "<form …></form>",
"cancelAt": null
}
}
Inyecta data.html en tu página (se auto-envía al banco). El cliente se autentica dentro del portal de su banco y es devuelto al successUrl / failureUrl del comercio. El estado se entrega vía el callback del comercio (clientConfig.callback).
Tanto revert como refund están soportados vía POST $MIGO_BASE/revert y POST $MIGO_BASE/refund con body {"transactionUid":"$UID","processor":"globalPay-PSE"} (esquema JWT-Bearer).
Datos de sandbox
bank.key = "0"(banco de prueba en QA) siempre aprueba.fiscalNumber = "1234567890"→ decline simulado.
Checklist de hecho
- Lista de bancos renderizada.
- HTML auto-enviado.
- URL de retorno manejada y webhook llegó.
Errores comunes a todos los rails
El middleware de pagos alternativos lanza own-codes de 4 dígitos (no el catálogo 7xxx del ALI Gateway):
| HTTP | own-code | Cuándo |
|---|---|---|
| 400 | 5000 | Params faltantes/inválidos (amount, channel, client, userId, customKeys, o processor) |
| 400 | — | processor no permitido para este cliente |
| 400 | 5004 | Config del cliente no encontrada |
| 400 | 2002 | Falló la creación de la transacción |
| 400 | 2003 | Monto fuera del rango permitido |
Entrega del estado
El estado del pago se entrega a través del callback del comercio que configuras en clientConfig.callback — ve Merchant Generic Callback. No hay un envoltorio de webhook fijo definido por la plataforma.
Checklist final
- Token de comercio enviado como
Authorization: Bearer $MIGO_TOKEN; transacción creada. -
nequiyglobalPay-PSEprobados en sandbox. - Rutas de refund/void probadas para
nequi,globalPay-PSE. - Recorrido del cliente cubierto para la forma de respuesta de cada rail (
payButton,html).