Guatemala — recetas de integración
Los rails que retornan un payload en el endpoint /payments de pagos alternativos para Guatemala son: BAM PaymentButton, Zigi, Akisi QR, Banco Industrial, QuickPay QR y Pronet. Cada sección de abajo es autocontenida: prerrequisitos, curl exacto, respuesta esperada, entrega del estado, datos de sandbox, errores comunes y un checklist de hecho.
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 que los integradores externos pueden alcanzar — el host más antiguo mw.dev.migopayments.com con /v1/mw-trxs es interno y usa un modelo de auth diferente (AWS SigV4); no lo uses.
export MIGO_BASE="https://sb-mw.migopayments.com"
export MIGO_CLIENT="<your-client-slug>" # e.g. "migoDeveloper"
export MIGO_TOKEN="<your-64-char-merchant-token>" # 64 hex chars
export MIGO_USER_ID="+50224865444"
El token de comercio de 64 caracteres es el mismo secreto que Migo emite para los Payment Links. Las rutas de Pagos Alternativos lo aceptan como token Bearer — ve Autenticación → Formato del header por endpoint.
Crea una transacción que reutilizarás en el resto de esta página (Migo retorna los rails habilitados para tu cliente dentro de paymentMethods):
export UID=$(
curl -s -X POST "$MIGO_BASE/api/v1/integrations/transactions" \
-H "Authorization: Bearer $MIGO_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"amount\": 50,
\"channel\": \"web\",
\"client\": \"$MIGO_CLIENT\",
\"userId\": \"$MIGO_USER_ID\",
\"customKeys\": { \"orderId\": \"recipe-test\" }
}" | jq -r '.data.uid'
)
echo "trx uid: $UID"
Inspecciona los paymentMethods retornados para confirmar cuáles de los rails de abajo tiene habilitados tu cliente. El conjunto habilitado se resuelve en runtime desde clientConfig.processors (por comercio, MongoDB) intersectado con la config de métodos de pago alternativo de la plataforma, por lo que depende del entorno y del comercio — cualquier array de ejemplo es solo ilustrativo. Si un rail que esperas no aparece, contacta a Operaciones de Migo.
BAM PaymentButton (bamPaymentButton)
País: Guatemala · Tipo: Botón hosteado (dominio BAM-Banco Agromercantil) ·
payment-intentsprevio: No · Payload de respuesta:url.
Prerrequisitos
clientConfig.processorsincluyebamPaymentButton.- Puedes renderizar un redirect externo desde tu checkout.
- Input opcional del usuario: número de cuotas.
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": "bamPaymentButton",
"data": { "installments": 1 }
}'
Respuesta esperada — el enlace de redirect está en data.data:
{
"success": true,
"message": "Success",
"data": {
"uid": "trx_…",
"type": "url",
"data": "https://pagosbam.com.gt/…",
"cancelAt": null
}
}
Redirige al cliente a data.data. El cliente autoriza el pago en el dominio de BAM y es devuelto a tu successUrl / failureUrl. El estado se entrega vía el callback del comercio (clientConfig.callback); el eco de installments depende del callback del comercio en lugar de estar garantizado.
Datos de sandbox
- Usa cualquier valor de cuotas
1..12. - La URL de redirect apunta al entorno de staging de BAM en sandbox.
Checklist de hecho
-
paymentMethodsconteníabamPaymentButton. - La respuesta de pago fue
data.type === "url", enlace leído dedata.data. - El redirect ocurrió, BAM devolvió el control, callback recibido.
Zigi (zigi)
País: Guatemala · Tipo: Redirect a billetera — el cliente autoriza dentro de la app Zigi ·
payment-intentsprevio: No · Payload de respuesta:url.
Procesar el pago
curl -X POST "$MIGO_BASE/api/v1/integrations/transactions/$UID/payments" \
-H "Authorization: Bearer $MIGO_TOKEN" \
-d '{ "processor": "zigi", "data": {} }'
Respuesta — el payload del challenge (type y data del procesador) está en data.data:
{
"success": true,
"message": "success",
"data": {
"uid": "trx_…",
"type": "<challenge.type>",
"data": "<challenge.data>",
"cancelAt": null
}
}
Abre el redirect desde data.data en un webview o vía deep-link a la app Zigi. El estado se entrega vía el callback del comercio (clientConfig.callback).
Reembolsos: revert/refund de zigi están disponibles en la superficie middleware-pay vía POST $MIGO_BASE/revert y POST $MIGO_BASE/refund con body {"transactionUid":"$UID","processor":"zigi"} (esquema JWT-Bearer, separado de esta superficie de token de comercio).
Checklist de hecho
- Cliente redirigido a Zigi, autorizó, devuelto, callback recibido.
Akisi / Akisi QR (akisi, akisiQR)
País: Guatemala · Tipo: Billetera Akisi — push (
akisi) o QR escaneable (akisiQR) ·payment-intentsprevio: No · Payload de respuesta:json(push) obase64(QR).
Procesar el pago — push
akisi (push) es una llave de procesador registrada, pero el handler de pagos alternativos solo tiene un caso de respuesta para akisiQR (QR). Una llamada push de akisi cae en la rama default del handler y no retorna ningún payload específico de rail. Usa la variante QR de abajo, o contacta a Operaciones de Migo para confirmar la ruta de integración push.
curl -X POST "$MIGO_BASE/api/v1/integrations/transactions/$UID/payments" \
-H "Authorization: Bearer $MIGO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "processor": "akisi", "data": {} }'
Procesar el pago — QR
curl -X POST "$MIGO_BASE/api/v1/integrations/transactions/$UID/payments" \
-H "Authorization: Bearer $MIGO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "processor": "akisiQR", "data": {} }'
Respuesta (verificada contra sb-mw.migopayments.com):
{
"success": true,
"message": "Success",
"data": {
"transaction_id": "12740927961946781727",
"type": "base64",
"data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJQAAA…"
}
}
data.data es un URI completo data:image/png;base64,…: insértalo directamente en <img src=...> sin ningún paso de decodificación. El cliente escanea la imagen renderizada desde la app Akisi. (type y data se toman directo del paymentRequest del procesador; para akisiQR esto es un URI de imagen base64.)
typeVersiones anteriores de esta receta describían la respuesta como { "type": "qr", "value": "data:image/png;..." }. El runtime actual retorna el payload en data.data, no en data.value. Si todavía tienes parsers leyendo data.value, cámbialos.
El estado se entrega vía el callback del comercio (clientConfig.callback).
akisiQR soporta revert vía POST $MIGO_BASE/revert con body {"transactionUid":"$UID","processor":"akisiQR"} (esquema JWT-Bearer, separado de esta superficie de token de comercio).
Checklist de hecho
- QR renderizado desde
data.data. - Callback recibido (o expiración manejada tras el TTL del QR).
Banco Industrial (bancoIndustrial)
País: Guatemala · Tipo: QR push de BI ·
payment-intentsprevio: No · Payload de respuesta:base64.
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": "bancoIndustrial", "data": {} }'
Respuesta — la imagen es un data-URI base64 en data.data:
{
"success": true,
"message": "success",
"data": {
"uid": "trx_…",
"type": "base64",
"data": "data:image/png;base64,…",
"cancelAt": null
}
}
Inserta data.data directamente en <img src=...>; el cliente lo escanea desde la app de BI. El estado se entrega vía el callback del comercio (clientConfig.callback).
Checklist de hecho
- Sandbox retorna una imagen data-URI base64 en
data.data. - El callback llega después de que el cliente escanea en QA.
QuickPay QR (quickPayQR)
País: Guatemala (también SV, HN, CR) · Tipo: Agregador QR interbancario ·
payment-intentsprevio: No · Payload de respuesta:json(con string del QR + referencia).
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": "quickPayQR", "data": {} }'
Respuesta — el type y data vienen directo del paymentRequest del procesador:
{
"success": true,
"message": "Success",
"data": {
"transaction_id": "…",
"type": "<paymentRequest.type>",
"data": "<paymentRequest.data>",
"cancelAt": null
}
}
El estado se entrega vía el callback del comercio (clientConfig.callback).
quickPayQR soporta revert vía POST $MIGO_BASE/revert con body {"transactionUid":"$UID","processor":"quickPayQR"} (esquema JWT-Bearer, separado de esta superficie de token de comercio).
Checklist de hecho
- Payload del QR renderizado desde
data.data. - El callback llega después de escanear en cualquier app bancaria participante.
Pronet (pronet) — referencias de efectivo
País: Guatemala · Tipo: Referencias de efectivo pagables en tiendas de conveniencia ·
payment-intentsprevio: No · Payload de respuesta:json.
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": "pronet", "data": {} }'
Respuesta — la referencia se ubica bajo data.data, con limitDate y total:
{
"success": true,
"message": "success",
"data": {
"uid": "trx_…",
"type": "json",
"data": {
"reference": "…",
"limitDate": "…",
"total": 50,
"cancelAt": null
}
}
}
Muestra data.data.reference al cliente; lo paga en una tienda de conveniencia Pronet. El estado se entrega vía el callback del comercio (clientConfig.callback) tras el flujo de confirmación en efectivo.
Las reversiones de pronet están soportadas vía el flujo de confirmación en efectivo.
Checklist de hecho
- Número de referencia de
data.data.referencemostrado al cliente conlimitDate. - El callback llega una vez que el pago en efectivo se confirma.
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 |
Recibiendo el estado del pago
El estado se entrega a través del callback del comercio que configuras en clientConfig.callback — el payload es lo que defina tu plantilla data de callback, no un envoltorio fijo de la plataforma. Ve Merchant Generic Callback.
Hoy no existe un firmador de webhook saliente en el código — la plataforma no emite actualmente un header X-Migo-Signature.
Checklist final
- Token de comercio autenticado (enviado como
Authorization: Bearer $MIGO_TOKEN) — ve Autenticación → Formato del header. - Una transacción creada;
paymentMethodscontiene cada rail que planeas exponer. - Cada rail disponible de arriba probado al menos una vez en sandbox; payload del rail leído de
data.data. - Rutas de refund/void probadas para los rails que las soportan.
- Llaves de producción rotadas por separado de las de sandbox (el token de sandbox no funciona en producción).