Become a payment provider
This page is for providers β push wallets, QR networks, banks, or cash rails (like akisiQR or Nequi) β that want Migo to route payments to your service. It describes what your service must expose so Migo can offer your rail to merchants.
In the integration, Migo is the orchestrator: a merchant creates a transaction with Migo, the customer chooses your rail, and Migo asks your service to produce the payment instruction. Your service owns the customer's payment experience and reports the result back to Migo.
Integration flow (akisiQR example)β
Merchant βββΊ Migo βββΊ your service: create payment / QR
β
βΌ
you return a QR / URL / reference, or push to the customer's app, + your transaction id
β
βΌ
customer pays in your app / scans the QR / approves the push
β
βΌ
your service βββΊ Migo webhook: "this payment was completed"
β
βΌ
(optional) Migo βββΊ your service: cancel / reverse
This is exactly what akisiQR provides: an API for Migo to create the akisi QR, and a webhook that tells Migo when the end user has paid it.
Required API servicesβ
1. Create a payment (QR / charge)β
An endpoint Migo calls to start a payment on your side. It receives the amount, currency, an external reference, and any customer identifier, and returns the payment instruction plus your transaction id.
- Request (from Migo): amount, currency, external reference, customer identifier (required for push rails like Nequi, where the request targets the customer's phone / app).
- Response (to Migo): your transaction id + the payment instruction in one of these shapes:
- a QR (base64 image or EMVCo string),
- a redirect URL to your hosted page,
- a structured reference (e.g. a cash/payment code), or
- a push to the customer's app β for push rails (like Nequi), your service sends a payment request straight to the customer's wallet (by phone number / user id). There is nothing for the merchant to render; the customer approves in your app and the outcome arrives through your webhook. In this case the response only needs to confirm the push was sent (your transaction id + a pending status).
- Expiration: the response must include the payment instruction's expiry (
expiresAt, or the validity window in seconds). After that time the QR / URL / push is no longer payable and you must notify theEXPIREDoutcome over the webhook.
If your push rail requires the merchant to supply or confirm a value first (e.g. the customer's registered phone number), expose a lightweight lookup so Migo can fetch it before creating the payment. Migo surfaces this to integrators as a payment intent.
2. Payment notification webhookβ
Your service must notify Migo when the end user completes (or fails) the payment β this is the authoritative result. Migo exposes a dedicated webhook URL per provider, and your service POSTs a JSON body when the payment reaches a terminal state.
- Sends to Migo: your transaction id (and/or the external reference), final status, amount, and any authorization code.
- Must be sent for every terminal outcome, and should be retried until acknowledged with a
200.
Webhook payloadβ
The fields below are the common contract across our existing rails (akisiQR, Nequi, β¦). The transaction identifier and the result code are mandatory; the rest are sent when your rail produces them. Exact field names are confirmed during onboarding.
| Field | Type | Required | Description |
|---|---|---|---|
transactionId | string | Yes | The id your service returned on create payment (or the external reference Migo sent). Migo uses it to locate the transaction. |
responseCode | string | Yes | Terminal result code β see mapping below. |
description | string | Yes | Human-readable status description (e.g. "Authorizado"). |
amount | string | Yes | Paid amount, as a string to avoid decimal loss. |
currency | string | When applicable | ISO currency code (e.g. COP, GTQ). |
authorizationCode | string | When available | Authorization / approval code from your side. |
responseCode mapping β the webhook must be sent for every terminal outcome, not only successful ones:
responseCode | Migo status | When you send it |
|---|---|---|
00 | APPROVED | the customer paid |
01 | DENIED | the payment was declined or the user chose not to pay it |
11 | CANCELLED | the customer or the system cancelled the payment |
12 | EXPIRED | the payment expired unpaid (agree the exact value with Migo if your rail uses a different one) |
Notifying approved payments is not enough. Your webhook must also fire when the payment is cancelled, when the user declines / chooses not to pay, and when it expires unpaid β so Migo can close the transaction and release the merchant instead of leaving it stuck in PENDING.
Payload examples:
{
"responseCode": "00",
"description": "Authorizado",
"amount": "30",
"commerce_name": "migoTest",
"transactionId": "33273710655533943897"
}
{
"responseCode": "00",
"authorizationCode": "ABC123456",
"description": "Pago autorizado",
"currency": "COP",
"amount": "50000",
"transactionId": "TRX-20240603-12345"
}
Migo acknowledges the webhook with:
{
"success": true,
"message": "Webhook received",
"data": {
"uid": "<migo transaction uid>",
"status": "approved",
"total": 30,
"externalId": "33273710655533943897"
}
}
POST over HTTPS with Content-Type: application/json, authenticated as agreed (see Authentication). Treat the call as successful only on an HTTP 200 with "success": true; retry on any other outcome until acknowledged.
3. Cancellation / reversal (if available)β
If your rail supports it, expose an endpoint Migo can call to cancel a pending payment or reverse a completed one. State clearly which is supported (cancel before completion, refund after) and any time window. If your rail does not support reversal, document that explicitly.
Other requirementsβ
Authenticationβ
Define how the two directions authenticate:
- Migo β your API: how Migo authenticates its calls to you (e.g. API key, OAuth2 client credentials, HMAC-signed requests, or mTLS).
- Your webhook β Migo: how Migo verifies the webhook came from you (e.g. a shared secret / signature header).
Support at least one industry-standard mechanism in each direction.
Limits & expirationβ
Declare your rail's operational constraints so Migo can validate before creating a payment and avoid charges your service will reject:
- Minimum and maximum amount supported, per currency (e.g.
GTQ 1.00βGTQ 50,000.00). State the currency's decimal precision too. - Expiration time of the payment instruction: how long the QR / URL / push is valid before it lapses (a fixed rail value, or configurable per transaction). Migo uses it to set
expiresAtand to expect theEXPIREDoutcome.
Sandbox & test credentialsβ
Provide a sandbox environment and test credentials so Migo can build and certify the integration without moving real money β including a way to simulate a successful payment, a failure, and an expiration.
Documentationβ
Provide written API documentation covering: endpoints and payloads, authentication, status values, error codes, the webhook contract, and the sandbox base URLs and credentials.
Next stepsβ
To start a provider integration, contact your Migo commercial or integrations contact with the items above. Migo will share the webhook endpoint, credentials, and the certification checklist.