What Fintech Teams Need in Bank Reconciliation Software
Post your first omnibus allocation locally
Post the omnibus allocation as your first transaction in a locally running clone of Formance Ledger on GitHub.
Post your first omnibus allocation locally
Post the omnibus allocation as your first transaction in a locally running clone of Formance Ledger on GitHub.
Bank reconciliation software at a fintech is engineering's problem before it is finance's. The engineer who integrated each payment rail wrote the scripts that compare PSP settlement files, bank statements, and custodian reports with the ledger. A monthly cadence worked when one bank account fed the company's ledger, but it fails when a dozen rails settle at a dozen speeds into one omnibus account.
In a typical failure, a PSP settlement file lands on a Tuesday with one column renamed. The parser, written against positional headers, maps the fee column into the net-amount field and keeps going; nothing throws. By Thursday, the bank-held omnibus balance disagrees with the ledger by an amount nobody can explain, and the auditor is on site Monday. The broken script is one of many per-rail scripts, and its original author has since left the team.
Fintechs hold customer money across many rails and shared accounts, so one error can leave funds unexplained, which is why fintech teams need bank reconciliation software that meets five requirements with six capabilities.
Regulators now require a daily cadence that per-rail scripts cannot deliver. The UK Financial Conduct Authority (FCA) requires safeguarding reconciliations once each reconciliation day under CASS 15, while the US Federal Deposit Insurance Corporation (FDIC) has proposed a daily reconciliation rule.
In the UK, the FCA's CASS 15.8.19R requires at least one internal safeguarding reconciliation each reconciliation day, and CASS 15.8.42R sets the same frequency for the external reconciliation against banks and custodians. The rule has applied since 7 May 2026, and firms must retain each reconciliation record for five years.
In the US, the FDIC's proposed rule, "Recordkeeping for Custodial Accounts" (12 CFR Part 375), would require banks to reconcile beneficial-owner records to funds on deposit daily. The FDIC issued the proposal on September 17, 2024, and has not published a final rule.
Bank reconciliation software must meet five requirements: duplicate-safe ingestion, version-tolerant parsers, separate line-level and aggregate checks, per-owner attribution of omnibus inflows, and point-in-time corrections.
Formance is an open-source, programmable core ledger that unifies fiat and digital assets with regulatory-grade traceability. It's more effective to enforce a requirement when a posting is written than to detect it afterward.
Duplicate-safe software must treat a retried PSP callback and a retried API payout as the same event as the original delivery, and refuse to post either twice.
Use idempotency keys scoped per external event: the PSP's transfer ID, the bank's transaction reference, or the payout ID you generated before the first attempt. Duplicate postings occur when a key is scoped per request instead of per event.
A webhook redelivered after a timeout carries a fresh request ID, so a request-scoped key does not match the original delivery. The same transfer posts again, and the ledger now owes a merchant money the bank already paid.
Duplicate payments also arise outside retry paths. A batch of business payments submitted twice, once by a scheduled job and once by a manual rerun, posts every payment twice. Your reconciliation cannot assume duplicates arrive only through retries.
The ingestion layer must version every provider schema and reject unknown fields. The parser in the opening scenario accepted the renamed column because it trusted column position.
Pin each provider to a declared schema version and match fields by header name. An unknown or missing header then fails the whole batch, quarantines the file, and triggers an alert without touching the ledger.
Formance Connectivity ingests and unifies data from external financial providers into a single data model, and schema versioning belongs in that layer. Formance does not hold or move funds; all money movement relies on your connected banks, PSPs, exchanges, or custodians, and Formance records and reconciles it.
Status codes also need a versioned contract: declare each provider's allowed status values, route any unknown value to an exception queue, and never treat an unknown value as settled.
In a hypothetical status-code failure, a parser script defaults an unknown status to settled and posts cash that never arrived.
Line-level checks and aggregate checks catch different failures, and both must run on every reconciliation day.
The line-level check starts with each ledger posting and looks for it in the external statement or settlement report. The line-level check can pass even when the bank balance is short because fees debited directly from the omnibus account have no ledger posting to look up.
The aggregate check asks whether the sum of ledger balances equals the balance the bank reports at the reconciliation point. The aggregate check passes when the card rail over-posted by the same amount the ACH rail under-posted, because the errors cancel in the total.
Run the two checks as two controls with two results. A design that reports a single result hides the failure the missing check would have caught.
Every movement into an omnibus account must be allocated to owner accounts in the same atomic transaction. All allocations succeed or fail together, so no money is left without an owner.
The transaction is written in Numscript, Formance's purpose-built language for describing financial transactions. Numscript describes a transaction's intent, so engineers and finance teams can both read it.
In the transaction, a $2,450,000.00 PSP settlement arrives through @counterparties:psps:provider:settlement, a boundary account allowed to run negative to record incoming cash.
The settlement enters the clearing account @escrow:settlement:001:inflow, which starts at zero, must return to zero and is then allocated to three merchants ($1,200,000.00, $800,000.00, and $425,000.00) and to platform fees ($25,000.00).
The merchant accounts are liability sub-accounts: their balances record money owed to merchants and are backed by the omnibus balance. The platform account records its fee income.
Together, the merchant and platform fee balances sum to the bank-held omnibus cash position.
The transaction history records the source account for each posting, so @counterparties:psps:provider:settlement shows which PSP settlement funded every merchant and platform fee balance.
// OMNIBUS_SETTLEMENT
// Event: allocate a PSP settlement to merchants and platform fee income
send [USD/2 245000000] (
source = @counterparties:psps:provider:settlement allowing unbounded overdraft
destination = @escrow:settlement:001:inflow
)
send [USD/2 120000000] (
source = @escrow:settlement:001:inflow
destination = @merchants:001:available
)
send [USD/2 80000000] (
source = @escrow:settlement:001:inflow
destination = @merchants:002:available
)
send [USD/2 42500000] (
source = @escrow:settlement:001:inflow
destination = @merchants:003:available
)
send [USD/2 2500000] (
source = @escrow:settlement:001:inflow
destination = @platform:revenue:fees
)
set_tx_meta("event_type", "omnibus_settlement")
set_tx_meta("settlement_id", "001")
The four outflows total USD 2,450,000.00, so the clearing account closes at zero.
Corrections must be appended with an effective date, never edited into a closed period. A late settlement webhook recorded on 1 July must count in the 30 June balance without editing June.
Bi-temporal ledger history handles late corrections: every posting carries both a recorded time and an effective time. The correction is appended on 1 July with an effective date of 30 June. The 30 June reconciliation point is then restated from the corrected view while the original run stays on the record.
Bank reconciliation software should provide six capabilities: matching, balance verification, exception workflows, monitoring, scheduling and integrations, and audit reporting.
The five software requirements set what the data and ingestion layers must guarantee, while the six software capabilities do the daily work of finding, explaining, and closing differences.
Software requirements 1 (duplicate-safe ingestion) and 4 (per-owner attribution of omnibus inflows) are ingestion and posting controls, so no software capability replaces them.
Automated matching pairs internal ledger records with external bank and PSP statements using rules your team defines, rather than a person comparing rows.
Look for matching on transfer ID, reference, amount, and date, support for one-to-many matches (one bank deposit covering many PSP payouts), and tolerance windows for timing differences on instant and batch rails.
Matching runs the line-level and aggregate reconciliation checks.
Balance verification compares expected and actual balances, including the sum of owner balances against the bank-held omnibus balance.
Matching alone does not show whether the books agree with the bank. Balance verification should flag drift and settlement errors as they appear, and it runs the aggregate check from the separate line-level and aggregate reconciliation checks as a separate result.
Exception workflows give every unmatched item a path to resolution. Look for exception queues with reason codes, assignment to an owner, aging, and a record of who resolved each item and how. Restrict manual matches with role-based permissions and approvals.
Dashboards should track match rate, exception rate, and the age of open exceptions, with alerts on drift, failed runs, and aging exceptions. Track the three metrics alongside uptime and latency.
A rising exception rate can point to a parser mis-mapping a field before balances visibly drift. Alerts should reach the team that owns the fix.
Reconciliation software must run on a schedule you control, daily or intraday, and ingest bank files, PSP APIs, SFTP drops, and webhooks.
Cut-off reconciliation supports point-in-time corrections. Check support for your banks' file formats (such as CAMT.053, BAI2, or MT940) and your PSPs' APIs before purchase.
Reconciliation software should produce reconciliation-day reports that auditors and regulators can use. When an auditor reviews a safeguarding reconciliation, they ask which run produced a number, what the books and the bank each showed, and who resolved every exception; a report that cannot answer those questions sends the team back to raw files.
Reports should show each result and the rule or check that produced it. Results should also export to your ERP or general ledger.
Seven questions test whether bank reconciliation software meets the five software requirements and six software capabilities above. Each question is a demonstration to run in a working system, because a design argument does not count.
Any question you cannot answer with a demonstration points to a missing control your bank reconciliation software must provide before an auditor or regulator finds it.