Saltar al contenido principal
Migo Docs

Procesar pago alternativo

Inicia el flujo de pago alternativo con un procesador específico seleccionado de la lista retornada en el momento de creación. La forma de la respuesta depende del procesador — Migo la normaliza mediante un discriminador data.type para que el frontend del comercio pueda renderizar la UI correcta.

POST https://mw.migopayments.com/api/v1/integrations/transactions/{transactionId}/payments

Consulta la entrada en el spec en vivo: POST /api/v1/integrations/transactions/{transactionId}/payments.

Recordatorio de auth. Toda llamada envía Authorization: Bearer <token>. Ve Autenticación para más detalles.

Petición — body unificado

El body es la misma forma para cada procesador. El integrador siempre puede enviar todos los campos documentados; el runtime solo lee las llaves que aplican al processor elegido. Los campos que no aplican son ignorados.

{
"processor": "bamPaymentButton",
"data": {
"user": "",
"phoneNumber": "",
"installments": 1
}
}
CampoTipoRequeridoNotas
processorstringDebe estar presente en el array paymentMethods retornado al crear la transacción.
dataobjectsí (puede ser {})Envoltorio unificado — ve el mapeo campo-a-procesador abajo. El runtime solo lee las llaves que aplican al processor elegido; todo lo demás es ignorado.

Mapeo campo-a-procesador

El integrador puede mantener una sola forma de body y solo llenar lo que aplica. Envía strings vacíos, {}, u omite campos — Migo ignora todo lo que esté fuera del payload documentado del procesador activo.

Campo en dataUsado por
user o phoneNumber (al menos uno)fri
installmentsbamPaymentButton

Procesadores sin requerimiento de data (envía data: {} u omite las llaves no usadas): bancoIndustrial, quickPayQR, akisiQR, pronet, zigi.

La forma unificada completa está documentada en el spec como AlternativePaymentDataDto.

cURL — BAM Payment Button (Guatemala)

curl -X POST https://mw.migopayments.com/api/v1/integrations/transactions/trx_8f3c2b1d9e7a/payments \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"processor": "bamPaymentButton",
"data": { "installments": 1 }
}'

Node.js

const res = await fetch(
`https://mw.migopayments.com/api/v1/integrations/transactions/${transactionId}/payments`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MIGO_JWT}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
processor: 'bamPaymentButton',
data: { installments: 1 },
}),
}
);

const { data } = await res.json();
// data.type drives the rendering branch
if (data.type === 'url') window.location.href = data.data; // Zigi, BAM Payment Button
if (data.type === 'base64') renderImage(data.data); // Akisi QR, Banco Industrial
if (data.type === 'json') renderStructuredPayload(data.data); // Pronet, QuickPay QR, FRI

Ejemplos de petición por procesador

Cada ejemplo usa la misma forma de body unificada. El integrador puede mantener el mismo tipo del lado del cliente y solo poblar los campos que aplican — Migo ignora las llaves fuera del payload del procesador activo.

FRI (push payment)

fri requiere al menos uno de user o phoneNumber.

{
"processor": "fri",
"data": {
"user": "fri-user-001"
}
}

BAM Payment Button (Guatemala, redirect hosteado)

{
"processor": "bamPaymentButton",
"data": {
"installments": 1
}
}

Procesadores sin data (envía {})

bancoIndustrial, quickPayQR, akisiQR, pronet, zigi — el cliente paga vía su app después de que Migo emite el QR / push notification.

{
"processor": "bancoIndustrial",
"data": {}
}

Forma de respuesta por data.type

data.typeEstrategia de renderCampo de payloadProcesadores de ejemplo
urlRedireccionar al cliente a la URLdata.data es el string de URLZigi, BAM Payment Button
qrRenderizar imagen QR a partir de un string EMVCo crudodata.data es el string del QR(ninguno actualmente)
base64Insertar el valor directo en <img src=...>data.data es un URI data:image/png;base64,…Akisi QR, Banco Industrial
jsonPayload estructurado (referencias)data.data es el payload estructuradoPronet, QuickPay QR, FRI
El campo se llama data.data, no data.value

El runtime emite el payload bajo data.data. Recetas anteriores (especialmente recipes/guatemala.md) usaban data.value — esa variante está desactualizada. Al parsear la respuesta, siempre lee data.data.

Ejemplo para type: "url":

{
"success": true,
"message": "success",
"data": {
"uid": "trx_8f3c2b1d9e7a",
"type": "url",
"data": "https://gateway.example.com/redirect/abc",
"cancelAt": 600
}
}

Ejemplo para type: "base64" (Akisi QR — verificado contra sb-mw.migopayments.com):

{
"success": true,
"message": "Success",
"data": {
"transaction_id": "12740927961946781727",
"type": "base64",
"data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJQAAA…"
}
}
El campo identificador varía según el riel

El identificador de la transacción en la respuesta vuelve como uid para algunos rieles (p. ej. Zigi, BAM Payment Button) y como transaction_id para otros (p. ej. Akisi QR, QuickPay QR). Los dos campos que siempre debes leer para renderizar son type y data.

Polling vs webhooks

Migo confirma el estado final mediante el webhook del procesador (APPROVED, DENIED, EXPIRED). Para UX puedes hacer polling al estado de la transacción cada 3–5 segundos mientras el cliente completa el rail; no dependas del polling como fuente de verdad — el webhook es autoritativo.

Errores

HTTPCausa
400Parámetros faltantes, procesador no permitido para este cliente, o llaves de data requeridas faltantes (la respuesta incluye data.missingValues)
401Falló la autenticación del lado del usuario (Ridivi)
405Procesador temporalmente no disponible (por ejemplo, Banco Industrial retorna un unavailabilityReason)
500El request al procesador no pudo ser procesado