Reconciliation
Money → Reconciliation compares what our partners say happened against what our ledger says happened.
Both sides are definitive about different things. The partner knows what moved on their rail; we know what we recorded. Reconciliation is the daily check that those two stories are the same one, and the breaks are where the interesting problems live.
Running one
Section titled “Running one”Load the partner’s statement for a period and match it. The CLI does the same job for bulk and scripted work:
make reconcile ARGS="profiles"make reconcile ARGS="check -profile paystack -file stmt.csv"Profiles exist because every partner’s statement format is their own. If a new statement will not parse, that is a profile problem, not a data problem — do not hand-edit the file into shape. A statement edited to parse is a statement whose reconciliation proves nothing.
The four kinds of break
Section titled “The four kinds of break”In our ledger, not in theirs. We recorded something the partner has no record of. Most often a timing difference at a period boundary — check the adjacent day before raising it. If it persists, it is serious: we may have told a merchant a payment succeeded that never moved.
In theirs, not in ours. The partner moved money we did not record. This is the worst direction, because it is money with no entry in our books, and nobody downstream will notice on their own. Escalate it.
Both, different amounts. Usually fees — a partner charge applied at their end and modelled differently at ours. Check the pricing configuration before assuming an error, because a systematic small difference is a mis-modelled fee rather than a mis-posted transaction, and it will recur every day until the model is fixed.
Both, different status. Usually timing: a transaction that completed after our status poller last looked. If it does not resolve by the next run, it is real.
The difference between an exception and a difference
Section titled “The difference between an exception and a difference”A timing difference resolves itself on the next period and needs recording, not investigating. An exception does not resolve and means one of the two systems is wrong about money.
Treating every difference as an exception buries the real ones. Treating every exception as a timing difference is how one becomes permanent. The test is simple: has it cleared by the next run?
Document what you find, every time
Section titled “Document what you find, every time”A reconciliation with a break and no note is worse than one not run. The next person sees a known break and cannot tell whether it was investigated and accepted or simply ignored, so they investigate it again — or, worse, they do not.
Write what the break was, what caused it, and what you did.
When nothing reconciles
Section titled “When nothing reconciles”If an entire statement fails to match, suspect the boundaries before the data: wrong period, wrong profile, wrong environment, a timezone difference at the cutoff. A whole-file mismatch is almost never a whole file of broken transactions.

