PAYMENTS

M-Pesa Integration: What Businesses Need to Know Before They Start

· 6 min read

M-Pesa integration comes up in almost every Kenyan software project. The Daraja API is reasonably well-documented, but there's a consistent gap between reading the documentation and having a reliable integration running in production. Here's what to understand before you start.

The Daraja API

Daraja is Safaricom's API platform — the name means "bridge" in Swahili. It exposes M-Pesa functionality as HTTP-based APIs. The main ones businesses use are:

For most businesses, you need STK Push and Transaction Status to start. C2B is required if you want customers to pay via Paybill without an app prompt. B2C is for outgoing payments.

What you need before you can go live

To integrate directly with Daraja, you need:

The go-live process involves a technical review. Safaricom will test your integration — not just the success path — and expects you to demonstrate correct handling of timeouts, cancelled payments, and insufficient funds. Plan for this review in your project timeline.

Sandbox vs production

The Daraja sandbox at developer.safaricom.co.ke lets you test without real money. Important differences to know:

Credentials change at go-live. Your Consumer Key and Consumer Secret in sandbox are different from your production credentials. Every environment you deploy to needs the right set — mixing them up is a common deployment error.

Test phone numbers are fixed. In sandbox, you can only use Safaricom's published test numbers (e.g., 254708374149). Attempting to use real Safaricom lines will fail.

Callback URLs must be public even in sandbox. Localhost won't receive callbacks. During development, use a tunnelling tool like ngrok or Cloudflare Tunnel to expose your local server to the internet for testing.

Sandbox accepts things production rejects. Test your error cases explicitly: what happens when the user cancels, when the transaction times out, when the user has insufficient funds. These scenarios often behave differently in production.

The four most common mistakes

Not handling the timeout properly. STK Push has a 30-second user response window. If the user doesn't respond — their phone is off, they dismiss the prompt, or connectivity drops — Safaricom sends a timeout callback to your server, not a payment confirmation. Your system must handle this state: mark the order as pending, not failed, and provide a way for the user to retry or for you to check transaction status manually.

Assuming the callback is the final word. Callbacks can occasionally be delayed or arrive out of order under network load. Build a reconciliation step that queries Transaction Status for any payment that hasn't received a definitive callback within a reasonable window. Don't rely solely on callbacks for financial records.

Hardcoding credentials. Consumer keys and access tokens expire and must be regenerated. Store credentials in environment variables or a secrets manager, not in your codebase. Access tokens in particular expire every hour — your code must request a new one automatically.

Slow callback URL response. When your server receives a callback, it must respond with a 200 status immediately — before doing any processing. If your server takes more than a few seconds to respond, Safaricom marks the callback as failed and may retry. Queue the callback for asynchronous processing and respond 200 right away.

Direct integration vs aggregator

Integrating Daraja directly gives you full control, no per-transaction fees beyond Safaricom's standard rates, and direct access to all API features. But it requires more development time, ongoing credential management, and handling of edge cases and reconciliation yourself.

Payment aggregators — Pesapal, IntaSend, PayHero, Flutterwave — wrap the Daraja API and provide a simpler integration surface with a dashboard, webhooks, and support. They charge a percentage per transaction (typically 1–3.5%), which adds up at volume, but the simplified integration and reduced operational overhead often justify the cost at smaller transaction volumes.

If your development team is small, your payment volumes are moderate, or you need to get to market quickly, start with an aggregator. You can move to direct Daraja integration later when volume and complexity justify it. The decision is a cost-versus-time trade-off, not a quality one.

← Back to blog

PAYMENTS INTEGRATION

Need help integrating M-Pesa?

We build and maintain M-Pesa integrations — STK Push, B2C, C2B — and handle reconciliation, error handling, and ongoing Daraja API changes.

See our payments service →

More from the blog

PROJECT MANAGEMENT

Technical Project Manager: Monoliths vs Microservices Architecture

IT SUPPORT

What IT Support Looks Like for a Small Business in Kenya