How the MTN MoMo Collections flow works
Collecting money with MTN MoMo is a three-part process: you authenticate, you ask the customer's phone to approve a payment, and then you confirm the result. The builder above follows the same order, so you can work through it top to bottom the first time you integrate.
- Get credentials. In the sandbox you create them yourself: pick a UUID v4 as your API user (step 1), then generate its API key (step 2). In production, MTN issues the API user and key through the Partner Portal, so skip straight to step 3.
- Get an access token. Send the API user and key as HTTP Basic auth to
/collection/token/. Tokens expire (typically after an hour), so cache one and refresh it rather than requesting a new token for every payment. - Request to pay. MoMo answers
202 Acceptedimmediately. That only means the request was queued. The customer still has to approve it on their phone. - Confirm the result. Either wait for MoMo to call your
X-Callback-Url, or poll the status endpoint with the sameX-Reference-Id. Do both in production: callbacks can be delayed or missed.
Base URLs and target environments
Sandbox calls go to https://sandbox.momodeveloper.mtn.com with X-Target-Environment: sandbox and currency EUR. Production calls go to https://proxy.momoapi.mtn.com with your country's target environment and local currency. Always confirm production values with MTN when you go live.
| X-Target-Environment | Country | Currency |
|---|---|---|
sandbox | Sandbox (testing) | EUR |
mtnuganda | Uganda | UGX |
mtnghana | Ghana | GHS |
mtncameroon | Cameroon | XAF |
mtnivorycoast | Côte d'Ivoire | XOF |
mtnbenin | Benin | XOF |
mtncongo | Congo | XAF |
mtnliberia | Liberia | LRD |
Sandbox test phone numbers
The sandbox simulates different outcomes depending on the payer number. Any number not listed here simulates a successful payment.
| MSISDN | Simulated outcome |
|---|---|
46733123450 | FAILED |
46733123451 | REJECTED |
46733123452 | TIMEOUT / expired |
46733123453 | Ongoing (stays PENDING) |
46733123454 | Delayed |
Sandbox behaviour occasionally changes. Check MTN's Sandbox Use Cases page if results don't match.
Common errors and how to fix them
- 400 Bad Request: usually an invalid UUID in
X-Reference-Id, a non-EUR currency in the sandbox, a malformed phone number, or a numeric (not string)amount. - 401 Unauthorized: the token expired, or the API user/key or subscription key don't match. Each product (Collections, Disbursements, Remittances) has its own subscription key.
- 409 Conflict: you reused an
X-Reference-Id. Every API user and every transaction needs a fresh UUID. - 411 Length Required: an empty POST (API key, token) sent without
Content-Length: 0. The generated code already handles this. - 500 / NOT_ALLOWED_TARGET_ENVIRONMENT: the target environment doesn't match your credentials, e.g. sandbox keys used with
mtnuganda.
Frequently asked questions
Why does MTN MoMo Request to Pay return 400 Bad Request?
The most common causes are an X-Reference-Id that is not a valid UUID v4, sending a currency other than EUR in the sandbox, a phone number with a "+" or leading zero, or sending amount as a number instead of a string.
Why does the MoMo token endpoint return 401 Unauthorized?
Either the API user/API key pair is wrong, the key was regenerated (which invalidates the old one), or the subscription key belongs to a different product. Collections, Disbursements and Remittances each have their own subscription key and their own token endpoint.
Does this tool send my API keys anywhere?
No. The code is generated entirely in your browser and nothing is sent to our servers or to MTN. Secret fields are never saved. For extra safety, keep "Use environment variables" switched on so keys never appear in the generated code.
Can I call the MoMo API directly from frontend JavaScript?
No. The MoMo API does not allow browser (CORS) requests, and putting your API key in frontend code would expose it to anyone. Always call MoMo from your backend and let your frontend talk to your backend.
What currency should I use in the MTN MoMo sandbox?
The sandbox only accepts EUR. In production use the currency of your target environment, for example UGX for mtnuganda or GHS for mtnghana.
Next steps
Building this in Node.js? Follow the full walkthrough:MTN MoMo Collections API in Node.js: sandbox to first payment.