Skip to main content
Fortlyn Technologies

PaymentsEngineeringTransport

Mobile money reconciliation is where the bugs live

Collecting payment is the easy part. Knowing, hours later, exactly what happened is where integrations quietly fail.

Fred Mwale · Chief Operations Officer · · 2 min read

Every mobile money integration demo works. A payment is initiated, a prompt arrives on the phone, a PIN is entered, a confirmation comes back. Ten seconds, end to end.

Production is not that. In production the confirmation arrives four hours later, or twice, or never while the money has definitely moved. The integration work is not in the happy path — it is in knowing, with certainty, what actually happened.

Three states, not two

Teams new to this model tend to build for success and failure. There is a third state that matters more than either: unknown.

A collection request has been sent. No confirmation has arrived. The money may have moved or it may not. Any system that forces this into either bucket will eventually either hand out a free ticket or take money for nothing.

We model it explicitly. An unknown payment holds the seat, does not issue the ticket, and enters a reconciliation queue with an escalating check schedule. Most resolve within minutes. Some take a day. A small number need a human, and the design has to make that a normal outcome rather than an incident.

Callbacks are a hint, not a source of truth

Provider callbacks arrive out of order, duplicated, and occasionally for transactions you have no record of initiating. Treating them as authoritative is how ledgers drift.

Our rule is that a callback triggers a query, and the query result is authoritative. It costs an extra API call per transaction and removes an entire category of reconciliation defect. Worth it every time.

Reconcile daily, not monthly

The single highest-value practice we adopted was daily automated reconciliation against the provider's own settlement file. Every transaction, matched on both sides, with exceptions surfaced to operations by mid-morning.

Monthly reconciliation finds the same defects thirty days later, by which point the agent involved has forgotten the day, the customer has moved on, and the pattern that would have identified the root cause has been buried under thousands of subsequent transactions.

Idempotency, again

It comes up in every payments post because it is the control that prevents the worst outcome. Client-generated keys, stable across app restarts and network retries, honoured by every endpoint that moves money.

An agent whose screen froze will press the button again. Design for that as the expected behaviour, because it is.

What to build first

If you are starting a mobile money integration, build the reconciliation report before the payment flow. It will tell you what questions the provider's API can actually answer, and that constrains the design more than anything in the integration guide.

More from the blog

Get new posts by email

Monthly at most. Product releases and writing like this.