How to Test Mobile Money Payments in Sandbox (Uganda Developer Guide)
To test mobile money payments in Uganda: (1) set up sandbox credentials on the MoMo Developer Portal and Airtel Money developer program, (2) test the happy path (successful payment), (3) test failure scenarios (insufficient balance, timeout, wrong PIN), (4) test your callback handler with delayed and duplicate callbacks, (5) verify your error handling and user-facing messages for each scenario. Never skip sandbox testing. The sandbox is free, simulates the full payment flow, and prevents embarrassing (and expensive) bugs in production.
Setting Up the MoMo and Airtel Money Sandboxes
Both MTN MoMo and Airtel Money provide sandbox environments for developers. These sandboxes simulate the real payment flow without processing actual transactions or moving real money.
MoMo Sandbox Setup
- Register on the MoMo Developer Portal (momodeveloper.mtn.com).
- Subscribe to the Collections API product.
- Provision a sandbox user: generate a UUID, POST to the provisioning endpoint, then create an API key.
- You now have: a subscription key, an API User ID, and an API Key. These work only in the sandbox.
Airtel Money Sandbox Setup
Airtel Money's developer program provides sandbox credentials through their own portal. The process varies and may require contacting their developer support team.
Callback Testing Setup
For both providers, you need a publicly accessible URL to receive callbacks during development:
- Install ngrok:
npm install -g ngrokor download from ngrok.com - Start your local server (e.g., on port 3000)
- Run:
ngrok http 3000 - Use the HTTPS URL ngrok provides as your callback URL
Note: the free ngrok URL changes every time you restart ngrok. If you are using a callback URL registered on the developer portal (not per-request), update it each time.
What to Test: A Complete Checklist
Most developers test the happy path and call it done. In production, the unhappy paths are where all the bugs hide. Here is the complete list of scenarios to test:
Success Scenarios
- Standard payment: request sent, customer confirms, callback received with SUCCESSFUL status
- Status polling: request sent, customer confirms, you poll the status endpoint and get SUCCESSFUL
- Both MoMo and Airtel Money (if you support both): test each provider separately
Failure Scenarios
- Insufficient balance: the customer does not have enough funds
- Wrong PIN: the customer enters an incorrect PIN (MoMo sandbox may auto-approve, so note this limitation)
- Transaction declined by the customer: the customer sees the prompt and actively declines
- Subscriber not found: the phone number is not registered for mobile money
Edge Case Scenarios
- Timeout: the customer never confirms (prompt expires). Verify your timeout handling works.
- Duplicate callback: your server receives the same callback twice. Verify idempotency.
- Missing callback: your callback endpoint is temporarily unreachable. Verify your polling fallback picks up the result.
- Concurrent payments: two payments for different orders happen at the same time. Verify they do not interfere with each other.
UI/UX Scenarios
- Verify the waiting state appears and is clear
- Verify the success screen shows the correct order details and amount
- Verify the failure screen shows a helpful message (not a raw error code)
- Verify the timeout screen offers a retry option
How to Simulate Failures in Sandbox
The MoMo sandbox is designed primarily for testing the happy path. Simulating failures requires some creativity:
Simulating Timeouts
Send a payment request but do not poll for the result immediately. Wait beyond your timeout period and verify your timeout logic triggers. Since the sandbox auto-approves, the callback will arrive as SUCCESSFUL, but your timeout logic should still work correctly (the frontend should have already shown the timeout message before the callback arrives).
Simulating Callback Failures
Stop your callback server after sending a payment request. The callback will fail to deliver. Verify that your polling mechanism picks up the payment result from the status endpoint.
Simulating Duplicate Callbacks
Manually send a duplicate callback to your callback endpoint (using curl or Postman with the same payload as a real callback). Verify that your handler processes it idempotently.
Simulating Invalid Phone Numbers
Send a payment request with a malformed phone number. Verify that the API returns an appropriate error and your app displays a useful message.
Testing with Aggregator Sandboxes
If you are using Flutterwave, EasyPay, or another aggregator, their sandboxes may offer richer failure simulation. Some aggregators provide test phone numbers that trigger specific failure scenarios (insufficient balance, declined, timeout). Check your aggregator's documentation for test numbers.
Sandbox Limitations (What You Cannot Test)
The sandbox is not identical to production. Be aware of these differences:
- No real USSD prompt: In sandbox, payments are auto-approved. You cannot test the actual customer experience of seeing the prompt on their phone and entering their PIN. You can only test this in production with real transactions.
- Timing differences: Sandbox callbacks arrive almost instantly. In production, callbacks may be delayed by network conditions, high load on the provider's side, or other factors. Your code must handle variable latency.
- Fee deductions: Sandbox transactions do not deduct fees. In production, the amount received in your merchant account is the amount charged minus the provider's transaction fee. Test with small real transactions in production to verify your reconciliation logic.
- Rate limits: Sandbox may have different (usually more lenient) rate limits than production. If your app sends many requests per second, you may hit production rate limits that you never saw in sandbox.
- Phone number validation: Sandbox may accept any phone number format. Production enforces stricter validation. Make sure your code formats phone numbers correctly before sending to the API.
Plan for a "soft launch" phase where you test in production with a small group of real users and small transaction amounts before opening to your full audience.
Moving from Sandbox to Production
The transition checklist:
- Apply for production credentials. Through the MoMo Developer Portal (and Airtel Money developer program). This involves a review process and business verification. Start early.
- Update environment variables. Switch base URL, API keys, subscription key, and target environment from sandbox values to production values. If you structured your code with environment variables from the start, this is a config change.
- Deploy your callback endpoint to production. No more ngrok. Your server must be deployed to a production environment with a real domain and SSL certificate.
- Test with small real transactions. Send a payment for a small amount (a few hundred UGX) to verify everything works end-to-end with real money. Check that the money actually arrives in your merchant account.
- Verify fee calculations. Confirm that the amount you receive matches what you expect after the provider's fees are deducted.
- Monitor closely for the first week. Watch your logs for errors, failed callbacks, and unexpected states. Production always surfaces issues that sandbox did not.
For a detailed production deployment guide, McTaba's Deployment and Going Live course (KES 4,999, approximately UGX 140,000) covers the full production checklist including environment management, monitoring, and rollback strategies.
Key Takeaways
- ✓The MoMo sandbox is free and simulates the full payment flow without real money. Do all your development and initial testing here.
- ✓Test every path: success, failure, timeout, duplicate callback, and missing callback. If you only test the happy path, production will surprise you.
- ✓Use ngrok or a similar tool to expose your local callback endpoint to the sandbox. Without a publicly accessible callback URL, you cannot test the complete flow.
- ✓The transition from sandbox to production involves new credentials, new base URLs, and a production approval process. Structure your code so this switch is a configuration change, not a code rewrite.
Frequently Asked Questions
- Is the MoMo sandbox free?
- Yes. The sandbox is completely free. No real money is involved, no transaction fees are charged, and you do not need a business registration to use it.
- Can I test Airtel Money and MoMo in the same sandbox?
- They are separate sandboxes. MoMo has its own developer portal and sandbox, Airtel Money has its own. You test each provider independently. If you are using an aggregator like Flutterwave, their single sandbox may simulate both providers.
- How do I test callbacks if I am developing on a laptop at home?
- Use ngrok (free tier) or Cloudflare Tunnel to create a public HTTPS URL that tunnels to your local server. This lets the sandbox send callbacks to your machine even though it is behind a home router.
- How long does production approval take?
- It varies by provider and use case. MoMo and Airtel Money production approval can take anywhere from a few days to several weeks. Aggregators like Flutterwave may be faster since they handle the provider relationship. Start the application process well before your planned launch date.
Ready to build real-world apps?
Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.
Apply to the McTaba Marathon