Skip to content

Money Movement Architecture for Multi-Rail Fintechs | Formance

Multi-rail fintechs send and receive payments through several providers and networks at once. Every settlement file, error code, and timing window comes from a different source, and when any of those sources change, the cost falls on whoever owns reconciliation.

With three rails live and a fourth in contract, every new integration makes the problem worse. Your team has watched a reconciliation job fail at 3 AM because a payment service provider (PSP) changed its settlement file schema. Two columns swapped, a date format shifted, and the custom script your team wrote eighteen months ago produced mismatches nobody caught until finance tried to close the month.

Underneath this multi-rail architecture is a build-vs-buy decision most teams haven't framed as one: build four core systems in-house — a ledger, a provider normalization layer, an orchestration layer, and reconciliation — or use infrastructure that already has them.

You’re deciding whether to build your own money movement architecture or buy infrastructure that can adopt new rails without piling up technical debt each time.

What is Money Movement Architecture?

A money movement architecture is the way your company connects its core ledger, banks, PSPs, orchestration logic, and reconciliation processes into a single, working system.

Money movement itself is the logic that moves funds between customers, accounts, and external providers across payment rails. The architecture is the system of record and orchestration layer for those flows. The funds themselves are held and moved by your connected banks, PSPs, and custodians.

Three properties separate a working money movement architecture from a pile of integrations:

  1. A core ledger: Acting as the source of truth for all balances and transactions, no matter which rail the transaction came from.
  2. Unified handling of different rails: Through a normalization layer that translates provider events into one shared internal data model.
  3. A clear boundary: Between product logic and provider-specific integration code, so adding a rail changes an adapter, not your checkout flow.

Without those three properties, you end up with point-to-point integrations held together by loosely-connected integrations. The setup works until that engineer leaves, the PSP changes its application programming interface (API), or the auditor asks you to prove fund attribution across your omnibus account.

And the pressure on that fragile setup keeps growing because running on a single rail is no longer an option for most fintechs.

Why Multi-Rail Is Now the Default

Multi-rail is the default because different rails are built for different things, including cost, settlement speed, availability, coverage, and whether a payment can be reversed. You can't run all three of the following from one rail:

  1. Payroll disbursement on Automated Clearing House (ACH), which is batched and cheap.
  2. Instant consumer payouts on Real-Time Payments (RTP) or FedNow, which settle in seconds and can't be reversed.
  3. European operations on the Single Euro Payments Area (SEPA) Instant, which is now a regulatory requirement.

Multi-rail orchestration is now a core architectural decision, particularly when every new rail you add changes how money moves through your system.

Where Current Money Movement Architectures Break

Current money movement architectures break when you bolt a new payment rail onto existing infrastructure and inherit its settlement model, error codes, timing, and reconciliation format. The failure modes are specific and predictable.

Double-posting on retries

Double-posting on retries happens when a client resends a payment request that the server has already processed. The network drops the response, the client retries without an idempotency check, and the server processes the same payment again.

Race conditions in concurrent settlement

Race conditions in concurrent settlement occur when two writes update the same balance simultaneously, without proper synchronization. Each write reads the stale state before saving its update, which can push the account into overdraft.

Deriv hit this problem with a custom mini-ledger on DynamoDB: it behaved correctly at low volume, but under concurrent traffic, it could not reliably keep balances consistent because the data store didn’t enforce double-entry or safe updates.

Ledger finality drift

Ledger finality drift happens when different settlement timelines across rails are recorded inconsistently. A ledger that posts some rail events right away but batches others can show an inflated available balance until the slower rail catches up. The drift is a design problem.

Omnibus account drift

Omnibus account drift is when the cash held in a pooled account no longer matches the trial balance from internal records. The bankruptcy of Synapse Financial Technologies showed this at scale, with an estimated shortfall of $65 million to $96 million between cash held in For Benefit Of (FBO) accounts and the trial balance.

Audit trail destruction from mutable entries

Audit trail destruction occurs when engineers update balance records in place rather than adding a new entry for each change.

Each rail produces its own event stream (authorization, settlement, return, chargeback) at different times in different formats. When those events overwrite balances rather than being added as separate entries, the full history of a single payment can be spread across multiple rail-specific systems, making it hard to reconstruct.

Technical debt compounding under rail expansion

Technical debt compounds when each new rail or country is bolted onto an architecture that was never designed for it. Before moving to Formance, Kulu had configured 44 business process types in their legacy system, each requiring separate configuration for every wallet-to-wallet transaction type. Each new rail multiplied the burden.

That situation explains how teams that add rails and countries, and fix the split design, become a major project that must be completed while the system is still live. Patches pile up until the team decides to rebuild from scratch.

Each failure mode stems from a ledger and reconciliation architecture that was never designed to handle more than one rail. You should treat money movement as a stack you either build deliberately or decide to buy.

Ledger-First, Vendor-Agnostic Design

A ledger-first, vendor-agnostic design is the foundation of a resilient money movement stack, whether you build it yourself or adopt existing infrastructure. It puts a purpose-built, double-entry core ledger at the center of your payment system as the main system of record.

Your core ledger and the integration layer around it need to enforce four rules.

  1. Double-entry at write time

Double-entry at write time means every financial event creates at least two postings (a debit and a credit) that add up to zero. The rule is enforced at the API boundary, so no code path can bypass it. A ledger that enforces double-entry makes it impossible for value to disappear or appear out of nowhere.

  1. Immutability with hash-linked history

Immutability with hash-linked history means posted entries are never edited or deleted. Corrections are made by adding a reversal posting that cancels the original. Each entry includes a cryptographic reference to the entry before it, so changing a past entry breaks the hash of every entry that follows. Tampering can't go unnoticed.

  1. Provider event normalization

Provider event normalization means that each rail's events are translated into a shared internal data model in the connectivity layer before they reach the ledger. ACH batch files and card network settlement files are all treated as the same kind of posting. The product code never sees the raw rail format; rail-specific adapters handle the translation.

In practice, the normalization looks like this. An ACH settlement and a card settlement arrive in different formats, but the ledger sees the same posting shape:

ACH settlement → ledger posting

send [USD/2 50000] (

source = @world:ach:nacha

destination = @users:1234:available )

Card settlement → ledger posting

send [USD/2 50000] (

source = @world:card:visa

destination = @users:1234:available)

Both postings move $500 into the same user's available balance. The only difference is the source account — @world:ach:nacha versus @world:card:visa — which preserves the rail of origin for reconciliation and audit purposes without leaking rail-specific logic.

Adding a new rail later means adding a new source account (for example, @world:sepa:instant or @world:rtp:fednow) and a new adapter, rather than rewriting how postings are created.

  1. Idempotency on all mutating operations

Idempotency on all mutating operations means every API call that changes state can be retried safely without creating a duplicate ledger posting. Without idempotency, retries create duplicates. The checks need to be durable and applied to every write API.

With those four rules enforced at the API boundary, the ledger becomes the system of record. Building those four rules from scratch is one of the four systems the build-vs-buy decision hinges on.

Dynamic Routing and Orchestration

Dynamic routing and orchestration sit atop the ledger. They coordinate balance checks, holds, Know Your Customer (KYC) gates, settlements, and payouts across providers. For payment flows, a centralized controller is a better choice than choreography because it maintains an authoritative record of every step, which you need for debugging, compliance, and recovery after a partial failure.

Dynamic routing decides which rail to use for each transaction based on the destination bank's capabilities, the amount, the time of day, the corridor, the cost, and historical success rates. The routing layer should be separate from core product logic so that adding a new rail remains a small, contained change.

The orchestration layer needs three things to stay reliable.

  1. Saga-style compensating transactions

Saga-style compensating transactions are how the orchestrator unwinds a multi-step workflow when one step fails. When a step fails, the orchestrator runs compensating transactions to undo the steps before it. If a compensation also fails, there should be a defined path for retries and operational review.

  1. Step-level idempotency

Step-level idempotency means each saga step can be retried safely because it detects a prior run and returns the cached result. Exactly-once delivery is hard in distributed systems, so the practical fix is to make each layer idempotent on its own.

  1. Cascading failover with state preservation

Cascading failover with state preservation is how the orchestrator handles a rail outage without losing in-flight work. When a rail is unavailable, transactions route to the fallback rail without affecting the user and without losing the state of the original attempt.

With saga compensations, step-level idempotency, and cascading failover in place, the orchestration layer can run multi-step workflows reliably. Sequences like hold funds, await KYC, and trigger payout chain across providers without losing state when a rail goes down.

The target architecture is straightforward to describe. The migration is where most teams get stuck, because you can't pause production to rebuild the ledger underneath it.

Path from Today to a Multi-Rail Money Movement Architecture

The path from today to a multi-rail money-movement architecture follows a specific order. Connecting new rails to a single-entry or inconsistently written ledger almost always increases the risk of reconciliation and consistency issues.

Phase One: Stabilize the existing ledger

Audit for single-entry patterns in which a balance changes without a matching counter-posting. Enforce double-entry and immutability at the database level, not only in the application layer. Add idempotency keys to every payment operation before any migration starts.

Phase Two: Standardize event schemas

Build a single internal format that all rail events map into before they reach the ledger. Keep network-level identifiers in the model, including Input and Output Message Accountability Data (IMAD/OMAD) for wires, trace numbers for ACH, and R-codes as received. Adding a new rail should mean writing a new adapter, not changing every downstream consumer.

Phase Three: Connect rails progressively

Use a strangler fig approach. Connect one new rail to the new architecture for new transaction types only. The result is a clean test environment running at production scale, without putting current volumes at risk. Run the new core ledger in shadow mode alongside the old system, reconcile differences programmatically, and flip the read path only when the discrepancy rate reaches zero.

Phase Four: Introduce rules-based routing

Start with a simple lookup table that decides which rail to use. Capture routing telemetry from day one, and move to dynamic routing only after you have enough data to inform it.

By the time routing telemetry is feeding decisions back into the system, the architecture is doing the work your custom scripts used to.

Build the Architecture, Stop Maintaining the Workarounds

Every new rail you connect to a brittle ledger adds reconciliation risk to the next close, and every custom script you write to match settlement files becomes another thing your team has to maintain. Building the architecture is the practical alternative.

A core ledger as the source of truth, normalized provider events, orchestrated workflows, and automated reconciliation is the pattern engineering teams end up with after hitting these problems in real systems. Whether you implement that pattern in-house or through a vendor is the build-vs-buy decision at the heart of multi-rail money movement.

Formance’s open-source ledger is licensed under MIT, with Numscript, Formance's purpose-built domain-specific language (DSL), describing what a transaction does in terms that both engineers and finance teams can read.

Money Movement Architecture for Multi-Rail Fintechs | Formance

_payments

Money Movement Architecture for Multi-Rail Fintechs

Engineering teams can start with the open-source ledger as the source of truth, then add the orchestration and reconciliation layers once the architecture is ready.