Build and test in the MTN sandbox, keep every key on the server, and only mark an order paid after your server has confirmed the status with MTN. Airtel Money needs its own integration or a provider that combines both.
What happens when a customer pays
- The customer chooses MTN MoMo at checkout and enters their MTN number.
- Your website’s server sends MTN a request to pay for the order amount, with a unique reference.
- The customer receives a prompt on their phone and approves it with their MoMo PIN. Your website never sees the PIN.
- MTN updates the payment to SUCCESSFUL or FAILED.
- Your server confirms that result with MTN, then marks the order paid and sends the confirmation.
In the MTN developer documentation this is the Collections product and its request to pay operation. Everything in this guide follows from one rule: the order is paid when MTN says so, not when the customer’s browser returns to a thank you page.
What you need before writing code
| You need | Where it comes from |
|---|---|
| A developer account | |
| A product subscription | Subscribe to the Collections product. The portal gives you a primary and a secondary subscription key. |
| A sandbox API user and API key | Created with the sandbox provisioning API, for testing only. |
| Live credentials | Issued once MTN has onboarded the business for live payments. Ask MTN Rwanda what the business must provide. |
| A callback address | A page on your own domain, served over HTTPS, that receives payment results. |
Test in the sandbox first
The sandbox lets you run the whole flow without real money. MTN’s documentation sets out three details worth knowing before you start:
The target environment for testing is sandbox. Live payments use the environment MTN gives you for Rwanda. - The sandbox currency is EUR. Live payments in Rwanda are in Rwandan francs (RWF), so make sure the currency is a setting, not hard coded.
- MTN publishes test numbers that return specific failures, such as an account not found or a service that is unavailable. Any other number returns success.
That last point matters. If you only test with your own number, every payment will succeed and the failure paths will never run. Use MTN’s test numbers to check what the customer sees when a payment fails, and what happens to the order.
Callbacks and status checks
There are two ways to learn the result of a payment. Your server can ask MTN for the status of a request, or MTN can call your callback address when the status changes. To receive a callback, the request includes your callback URL, and that URL must use HTTPS.
MTN’s documentation is clear that the callback is sent only once, with no retry if your server misses it, and recommends checking the status as a fallback. So build both:
- Listen for the callback, but treat it as a signal to check, not as proof.
- Ask MTN for the status before marking the order paid, and confirm the amount and reference match the order.
- Check payments that stay pending after a few minutes, so a missed callback never leaves a paid customer waiting.
- Process each reference once. A repeated callback must not create a second order or a second delivery.
Keep it secure
- Keep the API key and subscription key on the server. Never put them in browser code, a theme file anyone can download, or a public code repository.
- Create a new reference for each payment attempt and store it with the order.
- Check the phone number before sending the request. MTN Rwanda numbers begin with 078 or 079.
- Log each request and result without storing more personal data than you need.
- Show the customer a clear message while the payment is pending, and a way to try again if it fails.
Where Airtel Money fits
Building it into WordPress
Further reading
Official documentation behind the technical guidance in this article.