What is Payment Orchestration? A Technical Primer
Explore Formance on GitHub
See how the ledger can sit beneath your payment orchestrator, making every routed transaction auditable across PSPs.
Explore Formance on GitHub
See how the ledger can sit beneath your payment orchestrator, making every routed transaction auditable across PSPs.
Visa Europe showed what single-rail dependency costs on June 1, 2018, when a component within a switch in Visa's primary UK data center suffered a partial failure, preventing the backup switch from activating. The malfunctioning switch created a message backlog that slowed processing at both data centers.
The outage lasted roughly 10 hours, during which 5.2 million transactions failed across Europe, including 2.4 million in the UK, leaving merchants on the Visa network with no automatic fallback path. That single point of failure is what payment orchestration is designed to eliminate.
Payment orchestration is the layer that, per transaction, decides which payment service provider (PSP) receives the request and what happens when that PSP says no. It turns processor choice from hard-coded application logic into an operational layer that can be inspected, modified, and linked to reconciliation records.
Architecturally, payment orchestration depends on four components:
Orchestration controls where a payment goes, but cannot record what happened afterward. Without the fourth component, the routing decision is unreconcilable. A $15,000 charge succeeded somewhere, but the orchestrator cannot tell you which PSP's clearing account holds the funds, or whether the first failed attempt left a residue.
Four steps carry the engineering load of payment orchestration: routing, connector normalization, retry safety, and event-driven flow control.
The routing engine ranks PSPs per transaction inside the payment request path, weighing fixed attributes (BIN, currency, amount, geography, and MCC) against live signals (success rates, fees, fraud flags, PSP health). Cost and acceptance ranking both work at BIN granularity.
The biggest gains appear in cross-border routing, where a local acquirer cuts cross-border fees and lifts domestic authorization rates because issuers treat cross-border traffic as higher risk. Most teams start with static rules and add ML models optimizing for approval rate once volume justifies it.
PSP integrations differ in SDKs, API shapes, and HTTP status code handling. A connector framework hides that heterogeneity behind a single internal data model, handling request transformation, response translation, per-provider retry semantics, and circuit breakers.
Normalization also covers settlement data; one provider's transaction_id is another's pspReference, and fees may arrive as a single processing_fees or split into interchange_fee, scheme_fee and markup. Mapping everything to a single taxonomy is why later PSP integrations become configuration rather than new codebases.
Retry correctness is hard because failure is ambiguous. A decline is definitive, but a timeout leaves the outcome unknown, and retrying without an idempotency key that the PSP honors turns a network blip into a double charge.
Idempotency guarantees vary by provider (key scope, retention, length limits, and regional behavior), and multi-server deployments without a shared duplicate-check store further weaken the guarantee.
Fallback chains define ordered PSPs per region with health-based routing and circuit breakers, because sustained latency spikes and retry storms cascade through dependent services. Every attempt should be traceable as its own object (PSP name, reference, state, normalized error, and timestamps), giving retries a reconcilable history instead of a collapsed status field.
Orchestration platforms turn PSP lifecycle transitions into triggers, consuming webhook events through an asynchronous queue so handlers return quickly. Flow builders move coordination out of application code into declarative configuration, chaining steps such as hold funds, await KYC, capture at end-of-day, trigger a payout and write the posting.
For multi-step flows across services, the saga pattern is well-suited, as each step publishes an event that triggers the next, with compensating transactions rolling back on failure. When the sequence changes, you edit a flow definition instead of redeploying three services.
A production orchestration stack separates four responsibilities to stay auditable: Connectivity, Routing, Reconciliation, and Ledger.
We call this the CRRL stack. The top two layers move money while the bottom two prove where it went.
Connectivity adapters translate each PSP's proprietary request and response schema into a single internal data model. The adapter normalizes PSP-specific account, payment, and settlement data into a common internal model before writing ledger postings, so product code never sees the raw rail format. Adding a rail changes only the adapter; the checkout flow stays untouched.
Adapters are also where reconciliation bugs hide. When a PSP changes a file format or status code, the adapter quietly mismaps a field, and the mismap only surfaces when balances stop matching. Isolating each PSP behind its own adapter keeps schema changes localized.
The routing and logic layer houses the rules engine, where waterfall sequences, geographic split ratios, A/B PSP tests, and retry policies reside. Version control safeguards production.
For auditability, teams should store a reference to the rule version used for every transaction, along with the decline codes, the PSP and merchant account that handled the attempt, and the legal entity. Without version-controlled rule references, you cannot explain last month's routing decisions to an auditor.
The reconciliation layer ties each orchestrated transaction to its settlement record from each PSP and detects drift when PSP settlement reports diverge from internal records.
The reconciliation topology is often asymmetric: incoming payments reconcile 1:1 on the first leg (order to PSP, by transaction reference), then N:1 on the second leg, where many PSP transactions map to one settlement credit at the bank.
The core ledger is the double-entry system of record that makes routed transactions auditable through retries and settlement, and represents reversals as new balancing entries.
Numscript, Formance's language for financial transactions, expresses a gross-to-net settlement as one atomic multi-posting. Take this example of a $10,000.00 card settlement netting $9,700.00 after $120.00 markup, $50.00 scheme fees, and $130.00 interchange:
// CARD_SETTLEMENT
// Event: record a $10,000.00 card settlement net of markup, scheme, and interchange fees
send [USD/2 1000000] (
source = @counterparties:acquirers:a allowing unbounded overdraft
destination = {
970000/1000000 to @merchants:acme:available
12000/1000000 to @platform:expenses:fees:markup
5000/1000000 to @platform:expenses:fees:scheme
13000/1000000 to @platform:expenses:fees:interchange
}
)
set_tx_meta("event_type", "card_settlement")
set_tx_meta("settlement_id", "set001")
All four postings are committed together or not at all, so the fee is preserved per transaction rather than buried in a PSP invoice.
The other three layers depend on the core ledger as routing writes intent, connectivity writes PSP events, and reconciliation compares against external reality.
A single-PSP payment stack breaks for structural reasons: vendor concentration, integration sprawl per rail added, and routing decisions scattered across application code.
If the PSP goes down, rate-limits traffic, or declines a geography-specific segment, the stack has no alternative route and limited visibility into the cause. Every outage window, regional decline pattern, and unannounced rate limit reaches checkout unfiltered. There is no fallback path and no operational lever to pull while the incident is live.
Each added PSP or payment method, including buy now, pay later (BNPL) providers and local payment methods, brings its own request schema, webhook semantics, and settlement report format. Each addition creates a separate data model and reconciliation process, and integration work grows disproportionately as your team maintains a bespoke translation layer for each provider.
Without a central routing layer, "which PSP handles this transaction" is determined by application code, spread across checkout logic, retry handlers, and per-region branches. There is no central place where the rule is defined or audited, no way to change it without a deploy, and no reliable answer when an auditor asks why a specific transaction went to a specific processor last month.
Adding orchestration resolves single-PSP failures but introduces new ones: partial-capture risk after failover, reconciliation drift at high transaction volumes, and broken network token portability.
Partial-capture risk arises when an authorization succeeds at PSP A, the connection drops before the response reaches PSP A, and the capture routes to PSP B. A ghost authorization now sits open at PSP A: the customer's issuer holds funds against the authorization, the customer can be charged twice, and the reconciliation record never closes cleanly.
Partial-capture exposure widens across geography. If a retry routes to a different data center during a regional failover, the idempotency state may need to be visible across processing locations to reduce the risk of duplicate charges. Failover logic should also avoid assuming uniform capture semantics across processors and instruments.
Small per-transaction discrepancies across PSPs compound as volume rises. A 0.1% per-transaction discrepancy across three acquirers becomes a five-figure month-end exception queue; each unresolved line blocks the settlement close.
Timing differences across acquirers and later refund or chargeback events make those exceptions harder to trace. Reconcile at the transaction level rather than in daily batches. Batch reconciliation surfaces the drift only after it has compounded.
Network token portability breaks when teams using processor vaults try to move volume across PSPs. Re-tokenizing cardholder data creates migration work and may require customers to re-enter payment details.
Network-level tokens can reduce processor-vault lock-in when the relevant issuer, network, acquirer, and processor support the token flow. However, support and performance still vary by issuer, processor, and transaction context.
Five signals confirm that you need payment orchestration within your financial architecture: manual multi-PSP routing, geographic authorization variance, single-PSP outage exposure, cross-border expansion, and inconsistent retry logic.
Routing rules embedded in if statements require a code deployment for every change, and the operational drag compounds as the number of providers and payment methods grows. If your PSP count has moved beyond a simple primary-and-backup setup, hand-rolled routing is already the bottleneck.
A blended authorization rate can hide strong domestic debit performance and weak international credit performance. Local acquiring can help narrow the gap in some cases. Without signal-based routing, that variance is a report you read.
Partial outages can affect a specific region, rail, or payment method rather than the entire provider. You cannot integrate your way out mid-incident; onboarding a new acquirer directly can take many months.
Cross-border expansion introduces differences in authentication, acquisition, currency, and compliance across markets. Multi-market coverage means multi-acquirer by construction, and multi-acquirer without orchestration means one bespoke integration per market.
Each direct PSP integration carries its own retry implementation with its own assumptions about key retention, scopes, and timeout semantics. Centralizing the taxonomy can reduce duplicated engineering work, as multi-PSP fallbacks may recover transactions that would otherwise fail.
A programmable core ledger beneath the orchestrator records every fund movement the orchestrator triggers and makes those movements auditable across PSPs.
An orchestration platform routes payment instructions: a programmable core ledger records the resulting fund movements, while a reconciliation layer compares them with external statements across connected rails. If you collapse the orchestrator and the ledger into one layer, external PSP APIs become your source of financial truth by default, which is exactly the failure mode a separate ledger prevents.