Skip to main content
Migo Docs

Recipe template

This is the canonical structure for any country recipe. Copy it verbatim when adding a new market or rail. The structure is what makes the recipes consumable by both humans and integration agents.

## {Rail name} (`processorKey`)

> **Country:** … · **Type:** … · **Pre-call `payment-intents`:** … · **Response payload:** `url` | `qr` | `html` | `payButton` | `json`.

### Pre-requisites

- The merchant's `clientConfig.processors` includes `processorKey`.
- You have the long-lived 64-char merchant token (see [Authentication → Merchant token](/introduction/authentication#merchant-token)). Alternative Payments accept it as `Authorization: Bearer <token>`.
- Required user-collected fields: …

### Step 1 — Create the transaction

`​`​`bash
curl -X POST https://sb-mw.migopayments.com/api/v1/integrations/transactions \
-H "Authorization: Bearer $MIGO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "amount": 1000, "channel": "web", "client": "your-client-slug", "userId": "+50200000000", "customKeys": { "orderId": "…" } }'
`​`​`

Required fields: `amount`, `channel`, `client`, `userId`, `customKeys`. Expected response (truncated):

`​`​`json
{
"success": true,
"data": {
"uid": "trx_…",
"paymentMethods": [ "processorKey", … ]
}
}
`​`​`

### Step 2 — (Only if required) Fetch payment intent

`​`​`bash
curl -X POST https://sb-mw.migopayments.com/api/v1/integrations/transactions/$UID/payment-intents \
-H "Authorization: Bearer $MIGO_TOKEN" \
-d '{ "processor": "processorKey" }'
`​`​`

Returns the metadata your frontend needs (banks, sessions). The `payment-intents` handler only special-cases a few processors (`globalPay-PSE`, `fri`, `nequi`); others return `{ "success": true, "data": null }`.

### Step 3 — Process payment

`​`​`bash
curl -X POST https://sb-mw.migopayments.com/api/v1/integrations/transactions/$UID/payments \
-H "Authorization: Bearer $MIGO_TOKEN" \
-d '{ "processor": "processorKey", "data": { … } }'
`​`​`

The success envelope is `{ "success": true, "message": "…", "data": { … } }`. Read the rail payload from `data.data` (and processor-specific keys like `data.html` for `globalPay-PSE`). There is no top-level `statusCode` field in the JSON body.

### Step 4 — Status delivery

Payment status is delivered via the merchant callback you configure in `clientConfig.callback` — the payload is whatever your callback `data` template defines, not a fixed platform envelope. See [Merchant Generic Callback](/card-payments/merchant-generic-callback).

> No outbound webhook signer exists in code today — the platform does not currently emit an `X-Migo-Signature` header.

### Sandbox data

- `…`

### Common errors

The alternative-payments middleware raises 4-digit own-codes (not the ALI Gateway `7xxx` catalog):

| HTTP | own-code | When |
|---|---|---|
| 400 | `5000` | Missing/invalid params |
| 400 || `processor` not allowed for this client |
| 400 | `5004` | Client config not found |
| 400 | `2002` | Transaction create failed |
| 400 | `2003` | Amount outside the allowed range |

### Done checklist

- [ ] `POST .../transactions` returned `processorKey` in `paymentMethods`.
- [ ] `POST .../payments` returned the expected `data.type`, payload read from `data.data`.
- [ ] Frontend rendered the correct surface.
- [ ] Merchant callback received with the expected status in sandbox.

Country pages stitch one of these blocks per rail; the country header at the top pre-fills the auth/setup section once for the whole page.