Skip to main content
Migo Docs

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 the EXPIRED outcome over the webhook.
Push rails may need a pre-step

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.

FieldTypeRequiredDescription
transactionIdstringYesThe id your service returned on create payment (or the external reference Migo sent). Migo uses it to locate the transaction.
responseCodestringYesTerminal result code β€” see mapping below.
descriptionstringYesHuman-readable status description (e.g. "Authorizado").
amountstringYesPaid amount, as a string to avoid decimal loss.
currencystringWhen applicableISO currency code (e.g. COP, GTQ).
authorizationCodestringWhen availableAuthorization / approval code from your side.

responseCode mapping β€” the webhook must be sent for every terminal outcome, not only successful ones:

responseCodeMigo statusWhen you send it
00APPROVEDthe customer paid
01DENIEDthe payment was declined or the user chose not to pay it
11CANCELLEDthe customer or the system cancelled the payment
12EXPIREDthe payment expired unpaid (agree the exact value with Migo if your rail uses a different one)
Notify unsuccessful outcomes too

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:

akisiQR webhook
{
"responseCode": "00",
"description": "Authorizado",
"amount": "30",
"commerce_name": "migoTest",
"transactionId": "33273710655533943897"
}
Nequi webhook
{
"responseCode": "00",
"authorizationCode": "ABC123456",
"description": "Pago autorizado",
"currency": "COP",
"amount": "50000",
"transactionId": "TRX-20240603-12345"
}

Migo acknowledges the webhook with:

Migo acknowledgement
{
"success": true,
"message": "Webhook received",
"data": {
"uid": "<migo transaction uid>",
"status": "approved",
"total": 30,
"externalId": "33273710655533943897"
}
}
Delivery

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 expiresAt and to expect the EXPIRED outcome.

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.