Skip to content
Joseph Gitonga
<-All notes

How to reconcile M-Pesa payments with your invoices

2026-11-01 / 6 min / payments / m-pesa / reconciliation / billing

How to reconcile M-Pesa and bank payments with invoices: what to match on, wrong account numbers, partial payments, duplicates, and what to automate.

Get help with thisPayments: M-Pesa, cards, reconciliation and monitoring

The invoices went out in an afternoon. Working out who has paid takes the rest of the week.

M-Pesa makes collecting money easy and accounting for it hard. Customers pay into a Paybill with half the invoice number, pay twice, pay part, or pay from a relative’s phone. Here is a way to reconcile that holds up at month end, whether you do it by hand today or want software to do most of it.

Three records have to agree

Reconciliation is making three records tell the same story:

  1. The statement: what actually arrived in your M-Pesa or bank account.
  2. Your payment records: what your system or your team recorded as received.
  3. The ledger: which invoice or customer account each payment was applied to.

Most “missing payment” disputes are one of these disagreeing with the other two.

Work from the statement, not the SMS

The downloaded statement is the source of truth. SMS alerts get missed, deleted and forwarded. Import the statement, keep the file, and make sure importing an overlapping date range can never apply the same payment twice. The M-Pesa receipt number makes that possible: it is unique, so a receipt you have already applied is skipped, not counted again.

Match in this order

Take each statement line and try these in order, stopping at the first confident match:

  1. Receipt number. If the payment was confirmed through your integration, the receipt is already on record. Done.
  2. Account reference. On a Paybill, the account number the customer typed. Match it to an invoice or customer number, allowing for the common typos: missing prefixes, extra spaces, letter O for zero.
  3. Amount, phone and time. One open invoice for that exact amount from a customer with that phone number, paid around when it was due.
  4. Review queue. Anything else goes to a person, with the likely candidates already shown.

The review queue should be short. If it is long, the problem is upstream: customers are not being told what reference to use.

The cases that cause the arguments

Wrong account number

The money reached you but cannot be placed. Keep it in a visible unallocated list rather than an invisible suspense balance, and allocate it when the customer sends their M-Pesa message. Reduce these at the source: print the exact account number on every invoice and reminder.

Partial payments and overpayments

A partial payment reduces the balance; it does not leave the invoice “unpaid”. An overpayment becomes credit on the account for the next bill, not a refund nobody processes. Decide whether payments against an account clear the oldest invoice first, and apply the rule the same way every time.

Duplicates

A customer who paid twice has paid twice. Both receipts are real. Apply the first, hold the second as credit, and tell the customer, rather than letting the second quietly disappear.

Reversals

A reversed payment must reverse its allocation too, or the invoice stays marked paid on money you no longer have.

How often

Daily, if M-Pesa is how most customers pay. A day’s unmatched items take minutes. A month’s take a week, and by then the customer has forgotten which phone they used.

What to automate, and what not to

Automate the first three matching steps, the statement import, and the duplicate check. Those are rules, and rules do not get tired at month end.

Keep a person on the review queue and on anything that changes a customer’s balance without a confident match. AI can propose the likely match and explain why. It should not apply it unprompted; you need to be able to say why a payment landed on that account. That is how BillGrid handles it: proposed matches, confirmed by the team.

When it is not a reconciliation problem

If payments confirmed through your own integration are missing from your records, the problem is earlier, in the callback path. The note on missing STK push callbacks covers that.

If month end is still a week of matching by hand, payments reconciliation work starts with tracing a few real payments through your records and fixing where they fall out.


Read next