M-Pesa integration is a conversation, not a plugin
Many business owners imagine M-Pesa integration as a switch: connect it and payments appear. In reality your software is having a structured conversation with Safaricom's Daraja API over the internet. Your system asks Safaricom to do something, or Safaricom tells your system that something happened, and each message has to be received, understood and acted on correctly.
That framing matters because it explains where things go wrong. A conversation fails if one side does not hear the other, if a message arrives twice, or if the reply is delayed. Every real M-Pesa problem is a version of one of those.
The two directions money can flow
There are two core patterns, and most Kenyan businesses eventually need both.
- STK Push (Lipa na M-Pesa Online): your system triggers a prompt on the customer's phone for a specific amount. They enter their PIN, and you get a result tied to that request. This is ideal for checkout and online payments.
- C2B callbacks: the customer pays your paybill or till on their own initiative. Safaricom then posts the transaction to your registered confirmation URL. This catches everyone who pays directly without going through your checkout screen.
- B2C and B2B: paying out to customers or other businesses (refunds, disbursements, supplier payments) from your short code, which needs additional permissions and a security credential.
The callback URL is where integrations live or die
When money moves, Safaricom sends an HTTP request to a URL you registered - the callback. Your server has a few seconds to receive it and respond. If your endpoint is down, slow, behind a firewall, not on HTTPS, or returns an error, Safaricom's notification does not land. The payment still succeeded on M-Pesa, but your system is blind to it.
This is the single most common failure we see. The money is never lost - it sits safely in the business M-Pesa account - but the software shows the invoice as unpaid, staff chase a customer who already paid, and trust erodes. A robust integration treats the callback endpoint as critical infrastructure: always online, monitored, and able to record the raw message even if downstream processing fails.
Reconciliation depends on a clean account reference
The moment a payment arrives, your system has to answer one question: what is this for? The amount rarely answers it, because two customers can owe the same figure. The reliable signal is the account reference - the invoice number, member number, meter number or phone number attached to the transaction.
With a clean reference, software matches payments automatically and your ledger stays current without human effort. With a messy or missing reference - customers typing their name, or nothing at all - you fall back to manual matching, which is slow and error-prone. Designing the reference scheme well is half the battle, and it is a business decision as much as a technical one.
The details that quietly break real systems
A demo that works once is easy. A system you trust with daily revenue has to handle the awkward cases.
- Duplicate callbacks: Safaricom may deliver the same confirmation more than once. Idempotency handling ensures one payment is never recorded twice.
- Timeouts and retries: STK Push can time out if the customer is slow or has no airtime. Your system must handle a pending state, not assume success or failure.
- Sandbox vs production: test credentials behave differently from live ones. Always run real low-value transactions before launch.
- Token expiry: Daraja access tokens expire, so your system must refresh them automatically rather than caching one forever.
- Partial and wrong amounts: customers underpay, overpay or pay the wrong account. Your logic needs a plan for each.
Why doing it well takes more than sample code
Safaricom publishes sample requests, and a developer can get an STK Push firing in an afternoon. The gap between that and a production-grade integration is the reliability engineering: guaranteed callback capture, idempotent processing, automatic reconciliation, monitoring that alerts you when payments stop arriving, and a clear audit trail for every shilling.
That gap is exactly where businesses get burned by a cheap job that worked in the demo and then quietly dropped payments in month two. Getting it right the first time is far cheaper than reconciling a broken ledger later.
How Upeosoft approaches M-Pesa integration
At Upeosoft we treat M-Pesa integration as a payments reliability problem, not just an API call. We build callback endpoints that never drop a message, wire automatic reconciliation against your invoices, add idempotency and monitoring, and connect it to your accounting or ERP so the ledger updates itself.
We also design the account reference scheme with you so payments match cleanly from day one, and we test with real transactions before you rely on it. If you are integrating M-Pesa into a new system or fixing one that keeps losing payments, talk to us and we will map the right approach for your business.
