Skip to content
Silverconne

Mobile money reconciliation Zimbabwe

Reconciling EcoCash and ZIPIT payments against your sales ledger

Three payment rails, three different identifiers, and none of them is your invoice number. Here is a matching process that clears most receipts automatically and makes the rest somebody’s named job.

8 min read · published 6 May 2026 · updated 21 July 2026

Reconciling mobile money is not hard because the arithmetic is difficult. It is hard because the payment arrives carrying an identifier from the rail it travelled on, and your ledger is organised around an identifier you issued. Nothing joins the two unless you make it join.

What each rail actually gives you

What you get to match on, in practice
RailYou reliably getYou often do not getWorkable match key
Wallet payment to a merchant code (EcoCash and similar)A transaction identifier, the payer’s number, the amount, a timestampYour invoice number, unless the customer typed it and typed it correctlyPayer number plus amount inside a time window
ZIPIT and bank transferA bank reference, the amount, a value date, a narration fieldThe full narration — it is frequently truncated, and the customer wrote it anywayNarration fragment plus amount, then payer name
Gateway-initiated payment (you created the transaction)Your own reference, because you set it, plus the gateway statusNothing. This is the case you should be engineering towardsYour reference. Exact.

The reference field is the whole game

Every hour spent on reference discipline removes a day of matching later. There are only three situations, and each has one right answer.

  1. 01You initiate the paymentSet your own reference on the request. Then the match is exact and there is nothing to reconcile. Route as much volume here as you can — this is the argument for a payment link on the invoice rather than a number on it.
  2. 02The customer types a referenceMake it short, unambiguous and checkable. Drop characters people confuse, avoid spaces, keep it under about eight characters, and print it once, large, on the invoice. Accept it case-insensitively and accept it with the punctuation stripped, because that is how it will arrive.
  3. 03There is no reference at allMatch on payer identity plus amount inside a window, and treat the result as a suggestion for a human to confirm. Never post it automatically.

A match order that works

  1. 01Exact reference matchReference found, amount equals the open balance. Post it, no review.
  2. 02Reference match with a different amountPost it as a payment against that invoice and let the balance stand as a part-payment or an overpayment. Do not force it to the invoice total.
  3. 03Payer identity plus amount inside a windowOne candidate only. Present it to a person with both records side by side. Two candidates means no match.
  4. 04Everything else goes to a queueA named person works the queue daily. The queue having a name and a size is what stops it becoming a spreadsheet nobody owns.

The five cases that break a naive matcher

Fees deducted in transit
The customer sends the invoice amount and you receive slightly less. Post the receipt gross against the invoice and the charge to its own expense account. If you post the net amount, that invoice never closes and your ledger accumulates cents forever.
One payment, several invoices
A customer clears three invoices with one transfer. Your allocation model has to be many-to-many from the start; retrofitting it later means restating history.
Partial payment
Common and legitimate, especially on the 50% deposit model. An invoice needs an amount-paid and a balance, not a paid flag.
Reversal and duplicate
The same transaction identifier arriving twice must credit once. A reversal must reopen the invoice it closed rather than posting a negative receipt with no link back.
Timing across a cut-off
The customer paid at 23:50, your statement dates it the next day, and the invoice was raised in the previous month. Match on a window, and report on the invoice date rather than the receipt date.

Where the money sits while it is unmatched

In a suspense account for unallocated receipts, aged by day, with someone accountable for driving it to zero. Not in revenue, because you do not yet know whose revenue it is, and not in a spreadsheet, because a spreadsheet is not part of your trial balance.

Controls that keep it honest

  • Statements imported daily, not at month end. A three-week-old mismatch is an investigation; a one-day-old mismatch is a phone call.
  • An ageing report on unallocated receipts, reviewed weekly by someone who is not the person allocating them.
  • Manual matches recorded with who, when and why — the same audit trail you would want on a manual payment.
  • A monthly tie-out from your ledger balance to the wallet and bank statements. If it does not tie, you stop and find out why before you close.

What good looks like, in numbers

Numbers worth putting on a wall
MeasureStrugglingWorkableGood
Receipts matched with no human touchUnder 40%60–80%Over 90%
Days from receipt to allocationMonth endTwo to three daysSame day
Oldest unallocated receiptOlder than a monthUnder two weeksUnder three days
Customers wrongly chased for a paid invoiceEvery monthOccasionallyIt has stopped happening

None of this needs an expensive system. It needs the reference decided before the invoice is printed, the match order written down, and one person who owns the queue. The software should make those three things easy — that is genuinely the whole job.

IN SHORT

The four things worth remembering.

  1. 01Never auto-match on amount alone. It is the single most common cause of a customer being told they have not paid.
  2. 02Control the reference where you can initiate the payment, and shorten it where the customer has to type it.
  3. 03Unmatched receipts belong in a suspense account that is aged and driven to zero, never in revenue.
  4. 04Measure the auto-match rate. If nobody measures it, it decays.

IF YOU WOULD RATHER NOT BUILD IT

CheckERP

CheckERP imports wallet and bank statements, applies this match order, and keeps unallocated receipts in an aged suspense account you can actually work through.

QUESTIONS

What people ask after reading this.

Can we not just match on the amount?

You can, until two customers pay the same amount in the same week. Amount alone is a suggestion for a human, never an automatic posting.

Should the customer pay by wallet or by link?

By link where you can offer one, because you set the reference and the payment reconciles itself. Keep the wallet option, because plenty of customers will use nothing else.

NEXT STEP

Bring us the version of this you are actually stuck on.

Twenty minutes on your own setup is worth more than another article. We will tell you what we would change, and whether CheckERP is the right answer or the wrong one.

Free 20-minute call. We will tell you honestly if we are not the right fit.