Automating M-Pesa reconciliation
If you run a Kenyan business that takes payments on a paybill or till, this is almost certainly the automation with the shortest payback available to you. Here is how it works, where it gets difficult, and how to handle the cases that do not fit.
Need this done?
We do this work for Kenyan businesses every week. Free 30-minute call, honest answer, no deck.
The short version
- The problem is not the payments — it is that the payer name is the SIM holder, not the customer.
- Daraja C2B callbacks give you transactions in near real time.
- Matching should be layered: exact reference, then phone history, then fuzzy name, then amount.
- Only high-confidence matches post automatically; the rest go to a ranked exception queue.
- Typical build KES 250,000–800,000, with payback often under six months.
Why this is harder than it looks
On paper, reconciliation is trivial: money arrives, find the invoice, mark it paid. In practice, Kenyan mobile money creates a specific set of difficulties that defeat naive automation.
The payer name is wrong. An M-Pesa transaction carries the name registered against the SIM. When Duka Fresh Ltd pays you, the transaction says PETER MWANGI, because Peter is the storekeeper who happened to make the payment. Your invoice says Duka Fresh Ltd. No string comparison will connect them — but the phone number will, once you have seen it before.
References are unreliable. You ask customers to use the invoice number. Some do. Others type it with a typo, use last month's invoice number, put their own name, put the name of the person they spoke to, or leave it blank. Any system built on the assumption that references are correct will fail on a substantial share of transactions.
Amounts rarely match cleanly. Customers pay part of an invoice. They pay three invoices in one transaction. They pay a round number and leave a balance. They overpay and expect credit. One payment to one invoice is the easy case, not the normal one.
Timing is messy. Payment arrives before the invoice is raised. Payment arrives for goods collected last week. The payment lands on the 31st and the invoice is dated the 1st.
One till, many branches. Plenty of businesses run a single paybill across several locations, so the transaction contains no indication of which branch or salesperson the payment relates to.
Every one of these is solvable. But they explain why the finance team's spreadsheet exists, and why a system that only handles the clean cases will not retire it.
Getting the data: Daraja and the alternatives
Safaricom's Daraja API is the official route. The endpoints that matter here:
- C2B confirmation callbacks — your system is notified in near real time when a payment arrives at your paybill or till. This is the backbone of any reconciliation automation.
- C2B validation — optionally lets you accept or reject a payment before it completes. Powerful, and to be used carefully: if your endpoint is slow or down, you risk rejecting genuine payments.
- Transaction status and account balance — for periodic verification that your records agree with Safaricom's, which you should run daily regardless of how confident you are.
- STK push — for requesting payment from a customer, which pairs naturally with an invoice or a WhatsApp agent.
Practical notes from building these. Callbacks must be idempotent, because they can arrive more than once — use the transaction ID as a deduplication key and treat repeat delivery as normal rather than exceptional. Respond quickly and do the real processing asynchronously; a slow callback endpoint causes retries and compounds the problem. And log every raw payload before you parse it, because when a discrepancy surfaces three months later, the raw record is the only thing that settles the argument.
If you cannot get API access — some organisational structures make this slow — you can still automate by parsing statements exported from the M-Pesa business portal. It is less immediate and somewhat more fragile, but it removes the same manual work. We have built both; the statement route is a perfectly reasonable place to start while API access is being arranged.
The matching ladder
Do not attempt a single clever matching rule. Use an ordered ladder of increasingly permissive strategies, each with its own confidence score. Stop at the first one that produces a confident answer.
- Exact reference match. The account or reference field contains a valid invoice or account number that exists and is outstanding, and the amount matches. Highest confidence, and in well-disciplined customer bases this handles a large share of volume on its own.
- Fuzzy reference match. The reference is close to a valid number — a transposition, a missing prefix, an extra character. Normalise aggressively (strip spaces, punctuation and common prefixes), then apply edit-distance matching against outstanding invoices only. Confidence depends on whether the amount corroborates.
- Phone number history. This number has paid before and was linked to a customer account. This is the single most valuable signal in the Kenyan context, precisely because it routes around the payer-name problem. Every confirmed exception teaches the system a new number-to-account link, so accuracy compounds week by week.
- Fuzzy name match. Compare the M-Pesa name against your customer master and against known contact names on accounts. Handle initials, reordering, and the common Kenyan pattern of two given names and a family name in varying order. Treat this as a hint rather than a decision.
- Amount and timing. A payment exactly matching a single outstanding invoice raised in the last few days is suggestive. On its own it is weak evidence — but combined with a partial name or phone signal it is often enough.
- Combination matching. The amount equals the sum of two or three outstanding invoices for a candidate customer. Worth attempting, but cap the search: allowing arbitrary combinations produces coincidental matches that are worse than no match at all.
Set a confidence threshold above which the system posts automatically, and tune it against a labelled sample of your own historical transactions rather than guessing. The correct threshold is a business decision, not a technical one: it depends on whether a wrong automatic posting is a minor annoyance or a serious problem in your context.
Designing the exception queue
The exception queue is the product. Everything else is plumbing. If the queue is unpleasant to work through, your finance team will quietly go back to the spreadsheet.
A queue that works:
- Ranked by value and age, so the KES 400,000 unmatched payment from Tuesday is at the top, not buried under twenty small ones.
- Shows the system's guesses, in order, with the reasoning stated plainly: “This number paid Duka Fresh Ltd four times before” is far more useful than a bare confidence percentage.
- One-click confirm. Confirming the top suggestion should take a single action, because the top suggestion will usually be right.
- Learns from every correction. Confirming a match writes the phone-to-account link permanently. This is what makes the queue shrink over time rather than remaining a constant tax.
- Allows splitting and part-payment without leaving the screen, because that is what half the exceptions actually are.
- Reaches people where they are. A morning WhatsApp summary — “6 payments need your attention, KES 412,000 total” — gets acted on. A portal nobody remembers to open does not.
Posting safely to the ledger
Non-negotiable controls, in our view:
- Idempotency. The M-Pesa transaction ID is the key. A repeated callback must never create a second posting.
- Full audit trail. Every posting records what evidence produced it, which rule fired, what the confidence was, and whether a human confirmed it.
- Reversibility. Any automatic posting can be reversed by an authorised person, leaving both the original and the reversal visible.
- Daily verification. A scheduled job compares total received according to Safaricom against total posted in your ledger, and alerts on any difference. This is the control that catches problems you did not anticipate.
- No outbound payments. A reconciliation system should have read access to incoming transactions and write access to your own ledger. It should not be able to initiate a payment out. Keep the credentials separate so this is enforced by architecture rather than by policy.
The Kenyan edge cases
The ones that decide whether a system is genuinely useful:
- The customer who always pays from a different number. Three staff, three SIMs, one account. Support many-to-one number-to-account mapping from the start.
- Round-number payers. Owes KES 47,350, pays KES 47,000, and considers it settled. Needs a configurable tolerance and a policy on write-offs.
- Advance payments. Money arrives with no invoice yet. Post to a customer credit balance and match when the invoice appears, rather than dropping it into suspense.
- Reversals. M-Pesa reversals happen. Handle them explicitly, or a reversed payment will sit in your books as revenue.
- Wrong paybill. Payments intended for someone else, and payments to you meant for a different account. Both need a defined path.
- The busy period. Month end, December, a promotion. Volume spikes are exactly when the manual process fails and exactly when your automation must not.
- eTIMS alignment. If your invoicing is subject to KRA eTIMS requirements, reconciliation and invoicing must agree. Design them together rather than discovering the mismatch at year end.
Cost, timeline and payback
A reconciliation automation in the Kenyan market typically costs KES 250,000 to 800,000 to build, over three to six weeks. The variables are how many systems are involved — M-Pesa alone, or M-Pesa plus bank plus card — how accessible your accounting system is, and how complicated your part-payment and credit rules are.
The payback arithmetic is usually straightforward. If two finance staff each spend six hours a week on this, that is 624 hours a year. At a fully loaded KES 900 an hour, roughly KES 560,000 of labour, before counting the cost of errors, the cost of late month-end closing, and the cost of decisions delayed because nobody knows the cash position. Payback under six months is common, which is why we usually recommend this as the first automation for any business taking mobile money at volume.
One caution worth stating plainly: this project touches money, so it deserves more testing than a customer-service chatbot. Run it in shadow mode alongside the manual process for at least two weeks and diff the results before switching the manual version off. If the two disagree, you want to know why while the spreadsheet still exists.
Frequently asked questions
What is M-Pesa reconciliation?
M-Pesa reconciliation is the process of matching payments received into a paybill or till against the invoices, orders or customer accounts they were meant to settle, so that the accounting records reflect reality. It is difficult to automate naively because the payer name on an M-Pesa transaction is the registered SIM holder rather than the business, reference fields are frequently mistyped or left blank, and customers routinely pay in part or combine several invoices into one payment.
Can I get M-Pesa transactions automatically?
Yes. Safaricom’s Daraja API provides C2B confirmation callbacks that notify your system in near real time when a payment arrives at your paybill or till, along with transaction queries and account balance endpoints. You register the callback URLs against your shortcode. Businesses without API access can still automate by parsing the statements exported from the M-Pesa business portal, which is less immediate but works.
How accurate is automated matching?
In our experience, well-designed matching handles the large majority of transactions automatically once tuned to a specific business, with the remainder going to an exception queue. The exact rate depends heavily on whether your customers use reference numbers correctly, and it improves over the first few weeks as the system learns which phone numbers belong to which accounts.
What happens to payments that cannot be matched?
They go to an exception queue, ranked by value and age, with the system’s best guesses attached and a one-click way to confirm or correct. Crucially, the system learns from each correction: once a phone number is linked to a customer account, that link is remembered. The queue shrinks steadily rather than staying constant.
Is it safe to let software post to our accounts?
With the right controls, yes. Only high-confidence matches post automatically; everything else waits for a person. Every posting is logged with the evidence behind it and can be reversed. Nothing initiates an outbound payment. In practice automated posting is usually more accurate than manual keying, because it never gets tired at 6pm on the last day of the month.
The team at AI Consultant Kenya
AI and automation consultants, Nairobi
We build AI and automation systems for Kenyan businesses — workflow automation, WhatsApp AI agents, custom development and team training. Everything we write comes from work we have actually delivered here, under Kenyan conditions.