Integrating PesaPal Payments in Uganda: A Developer's Practical Guide
PesaPal is one of the most widely used payment aggregators in East Africa. It provides a single API to accept MTN Mobile Money, Airtel Money, Visa, and Mastercard payments. After integrating PesaPal across multiple client projects — including SAGECO Evergreen, Property Masters, and Tropical Gardens Hotel — here's a practical guide based on what actually works in production.
How PesaPal Works
The payment flow has three stages: First, you register an order with PesaPal to get a payment URL. Second, the user is redirected to PesaPal's payment page (or an iframe is embedded) where they choose their payment method and complete payment. Third, PesaPal sends an IPN (Instant Payment Notification) to your backend callback URL — this is how you know the payment actually succeeded.
Getting Started: Authentication
You need a PesaPal merchant account. Once approved, you receive a Consumer Key and Consumer Secret. You'll use these to generate a bearer token, which is required for all API calls. The token expires, so you need to fetch it fresh when needed rather than hardcoding it.
Registering an Order
To create a payment, you register an order with PesaPal's API. You send the amount, currency (UGX), description, and a unique order ID from your system. PesaPal returns a payment URL that you redirect the user to. The order ID is your anchor — PesaPal uses it in the IPN callback so you can match the payment back to your internal transaction record.
The IPN Callback: Where Most Bugs Live
The IPN callback is the most critical and most error-prone part of the integration. When a payment completes (or fails), PesaPal sends a POST request to your callback URL with the payment status. Your backend must handle this request and update your database accordingly.
Common issues we've encountered:
- Double IPN notifications: PesaPal sometimes sends the same IPN twice. Your handler must be idempotent — processing the same notification twice should not create a duplicate transaction record.
- Delayed notifications: MoMo payments can take 10-30 seconds to process. Your UI should show a pending state, not assume failure.
- Test vs. Live mode: PesaPal has a sandbox environment. Always test in sandbox first, then switch the base URL for production. The credentials are different for each environment.
- HTTPS requirement: PesaPal requires your IPN callback URL to be HTTPS. This means you need an SSL certificate even in development.
Production Pattern: Service-Role Updates
In one project (Property Masters), we initially updated subscription status from the client side after receiving the IPN callback. This was unreliable — if the user's browser was closed or the network dropped, the subscription wouldn't activate even though payment succeeded. The fix: move the IPN handler to a serverless function that uses service-role credentials to update the database directly, independent of any browser session. This ensures payments are always processed, even if the user navigates away.
Transaction Limits
One thing to watch for: PesaPal merchant accounts have transaction limits that depend on your verification status. New or unverified accounts may be capped at low amounts (we've seen UGX 30,000 limits). You need to work with PesaPal support to increase these limits as your business grows. Build your system to handle payment failures gracefully and display meaningful error messages to users.
Supported Payment Methods in Uganda
- MTN Mobile Money (MoMo): The most popular payment method in Uganda. Users receive a USSD prompt on their phone to confirm payment.
- Airtel Money: Similar to MoMo but on the Airtel network. Slightly different callback timing.
- Visa / Mastercard: Card payments through PesaPal's PCI-compliant infrastructure. Less common for small transactions but important for larger payments.
Conclusion
PesaPal is a solid payment aggregator for the Ugandan market, but the IPN callback flow requires careful engineering. The key principles: make your handler idempotent, use service-role updates for database changes, handle the pending state in your UI, and always test in sandbox before going live. We've integrated PesaPal across three production projects and these patterns have held up reliably.
Need help with your project?
DeryCode builds enterprise software, AI systems, blockchain infrastructure, and digital platforms.
Start a Conversation →Related reading
- What is DeryCoin? Uganda's First Community Blockchain Token — ⭐ Featured · Blockchain
- How Digital Banking Software is Transforming SACCOs in Uganda — Banking Tech
- Building a PWA: Why Progressive Web Apps Are Perfect for Uganda — Web Development