Back to Blog
Engineering · Fintech

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:

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

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

← Back to all articles