A three-way payment reconciliation that can recompute any past month byte for byte.
It matches a fintech’s own ledger against its payment processor’s settlement report and its bank statement, and puts only the genuine differences in front of a person, with the evidence behind each one.
- Result
- 1,332 rows in, 7 for a person to review
- Services
- Next.js web app + Python worker
- Bank format
- The ISO 20022 statement standard (camt.053)
- Demo month
- September 2026: 653 ledger rows, 612 settlement lines, 67 bank entries
The principle underneath
Money is stored as whole cents, never as rounded decimals. Rounding would create fake differences in the very place this system looks for real ones.
Walkthrough
Six decisions, each one defended.
01 · three sources
Two-way matching leaves blind spots
Each source sees a different part of the same money’s journey. The ledger says what customers paid, the processor’s report says what it kept and how it bundled payouts, and only the bank statement shows cash received. Three of the five problems planted in the demo month are invisible to a two-way match:
- Ledger and processor agree that payout PO-20260914 (EUR 1,752.23) was paid. Only the bank shows it never arrived.
- The ledger says EUR 316.85 and the bank received EUR 311.76. Only the processor’s report splits that into a EUR 4.69 fee and a real EUR 0.40 shortfall.
- One bank credit of EUR 10,624.87 pays for 50 card payments. Only the processor’s report says which 50.
02 · import
The same file cannot be imported twice
Every file gets a fingerprint, so the same statement can’t be imported twice under a different name. (The fingerprint is a SHA-256 the database computes itself, so the uploading program can’t supply a false one.)
A file the parser rejects is kept as evidence, with the reason written down, and can never be used in a reconciliation. A rejected file is a recorded outcome, not a crash.
03 · matching
Every row ends up in exactly one place
Every row lands in exactly one place, and the database double-checks every match’s arithmetic before a run can finish.
Matches on the demo month
65, including one 50-to-1 deposit
Sent to a person
7 exceptions: 4 planted, 3 timing
04 · exceptions
Decisions are added, never edited
Every break reaches a queue with a plain-language explanation and the evidence rows behind it. Resolving one takes a reason code and a note. The database refuses any change or deletion: a correction is a new entry that supersedes the old one, and both stay visible. If two people resolve the same item at once, exactly one gets through and the other is told who was first.
The cost: in the demo, anyone can sign in as any synthetic account, and one person can resolve and then correct their own decision. Real use needs real authentication and a preparer/approver rule.
05 · jobs
A bad file can’t jam the queue
A file that crashes the system can’t jam it. The failure is logged, and only a controller can retry it.
06 · replay
Any month can be recomputed and proved identical
The engine uses nothing but the three stored files and its own version: never the clock, the database, randomness or the machine’s settings, and a test inspects its code for any of these. A replay is recorded as a new run, linked to the original, and shown as identical or different. A difference is kept as evidence, never discarded. Every daily reset of the public demo checks that the demo month still reproduces exactly.
Limits
What this demo does not prove.
Synthetic data only.
“Orrery Payments” and “Demo Bank” are fictional. No real people, accounts, IBANs or transactions have been through it.
No real sign-in.
Anyone can act as any demo account, and there is no separation of duties between preparer and approver.
Simple matching rules.
Calendar-day windows with no bank-holiday calendar, exact references, EUR only, and one camt.053 version.
No regulatory claim.
It records and enforces what is described here. Whether that satisfies a given regulator is for the firm to judge.
Not client work.
Nothing here has been through a real audit, regulator or production incident. It shows the approach, not a track record.
Further limits are in the design rationale.
Describe the month that didn’t reconcile.
One paragraph, no customer data needed.