Your internal record of what customers paid and your provider's record of what they settled will not match. That is normal. What matters is whether you find out from a scheduled job that expects it, or from an accountant six months later who cannot close the books.
Six reasons, all structural, none of them a bug.
Timing. An authorisation is not a capture and a capture is not a settlement. Money leaves the customer, sits with the acquirer, and lands in your account days later. Any snapshot taken between those events shows a difference that is entirely correct.
Fees come out of settlement, not the transaction. You charged £100. You will receive something less than £100, and the deduction may be per-transaction, batched daily, or invoiced monthly depending on the provider. If your ledger records £100 and your bank shows £98.20, both are right and neither reconciles without modelling the fee explicitly.
Refunds settle on their own schedule, often netted against other activity rather than appearing as a discrete outbound movement.
Chargebacks arrive late. Weeks, sometimes months, after the original payment, with their own fee, and they can be reversed again if you win the dispute. A chargeback reaches back into a period you have already closed.
Currency conversion. If you charge in one currency and settle in another, the rate applied is the provider's at settlement time, not yours at transaction time. That difference is real money and it belongs somewhere in your accounts.
Partial captures and partial refunds break any assumption that one payment equals one amount.
Almost every system starts here: a balance column on the
user, or a paid boolean on the order, updated in place as
things happen.
It fails the first time something arrives out of order, and it fails silently. A chargeback lands and decrements a balance. Now the number is right but there is no record of why it changed, no way to reconstruct the balance at any past date, and no way to answer the question an accountant will eventually ask: show me every movement that produced this figure.
The deeper problem is that a mutable balance has no history. When it is wrong - and it will be - you cannot tell when it became wrong.
The fix is a ledger, and it is much simpler than accounting terminology makes it sound. Three rules:
Fees, chargebacks, FX differences and refunds all become ordinary entries between named accounts. Nothing needs special handling because everything is the same shape.
payment #4471 £100.00 captured customer:4471 +100.00 cash:acquirer -100.00 settlement, two days later cash:acquirer +98.20 expense:psp_fees +1.80 cash:bank -100.00
If the sum of entries is not zero, you have a bug - and you find out immediately, from an invariant, rather than from a quarterly close.
With a ledger in place, reconciliation stops being an investigation and becomes a job that runs nightly:
The important word is unmatched. A reconciliation that expects the numbers to be equal will alert constantly and be ignored within a fortnight. One that expects specific differences and flags only the unexplained ones gets read.
A reconciliation job that cries wolf is worse than none, because it teaches the team that the alert means nothing.
Do not fix them by editing the ledger. That reintroduces exactly the mutability the design exists to prevent.
Post a correcting pair of entries against a suspense account, and keep the original. The suspense balance becomes your open-questions number - a figure someone can look at weekly and work down. It should trend to zero. When it does not, that is a signal worth having rather than a discrepancy buried inside an aggregate.
None of this is exotic. It is standard practice in finance and unusual in application code, mostly because a balance column works fine right up until the first chargeback.
The cost of adding a ledger to a live system that never had one is substantially higher than building it in - you are reconstructing history from transaction logs that were never designed to support it. If you are handling money and you have a mutable balance somewhere, that is the thing to fix first.
We design payment ledgers and reconciliation, including retrofitting them into systems that started with a balance column. If yours does not currently reconcile, we can tell you why.