Provider-Agnostic Fintech Architecture: The Hidden Cost of Putting Provider Logic in Your Product

Key takeaways

  • Provider coupling is never an architecture decision. It arrives one delivery decision at a time, and by the time anyone names it, the provider’s data model has become the product’s data model.
  • Stripe, Wise, and Airwallex each use a different vocabulary for a payout, and none of their terminal happy-path states means the beneficiary has the money.
  • The switching cost is not the connector. It is the number of product decisions allowed to depend on the first provider: internal IDs, UI copy, reconciliation keys, support scripts.
  • Containment takes four layers: product contracts, orchestration, provider adapters, and a product-owned financial record.
  • The diagnostic is the Second Route Test. Can you add a second provider without changing your status vocabulary, notification copy, schema, or support runbook?

A fintech team rarely decides to build long-term dependency on one infrastructure provider. It happens one sensible delivery decision at a time.

The first integration needs to ship, so the product stores the provider’s payment status directly. Onboarding follows its field names. Reconciliation uses its report format. Within two quarters, an integration has become part of the product’s internal vocabulary.

That holds up while one market runs through one provider. The cost surfaces when the business needs a second route, and what the commercial team scoped as adding a route turns into coordinated change across the interface, the backend, operations, and reporting.

The problem is not using third-party providers. Every modern financial product does. The problem is letting provider-specific behavior define the product itself.


What counts as provider logic?

Provider logic is every assumption the product makes about how a particular provider behaves. The clearest place to see it is payout state.

Stripe models a payout as pending, then in_transit, then paid. The payout object documentation carries a warning most teams read once and forget: some payouts that fail might initially show as paid, then change to failed. The state that looks terminal is not reliably terminal.

Wise moves a transfer through incoming_payment_waiting, processing, funds_converted, and outgoing_payment_sent. Per Wise’s status documentation, that final state does not guarantee the recipient bank has credited the beneficiary. The failure path runs outgoing_payment_sent to bounced_back to processing to cancelled to funds_refunded, so the state machine moves backward. Wise also warns that new failure codes get added over time, and that integrators should handle codes they do not recognize.

Airwallex uses uppercase statuses including SCHEDULED, PROCESSING, SENT, PAID, and FAILED. Earlier API versions used a different set entirely, including IN_REVIEW, READY_FOR_DISPATCH, and DISPATCHED, which Airwallex still maintains as separate legacy documentation. Its changelog records adding PAID beyond SENT for visibility after dispatch.

That last detail is the argument in one line. A provider appended a state past what had been the end of the lifecycle. Any product that hard-coded SENT as completion did not get a feature. It got a defect, in production, on someone else’s release schedule.

StripeWiseAirwallex
Happy-path terminal statepaidoutgoing_payment_sentSENT, then PAID
Means beneficiary has funds?No. A failed payout can first appear as paidNo. Does not guarantee the recipient bank creditedSENT means dispatched; PAID added later
Reversal pathfailed after paidbounced_back, cancelled, funds_refundedFAILED, CANCELLED

Three vocabularies, three definitions of done, none of which answers the question the customer is asking. Surface them directly and notifications, support scripts, and reporting all have to know all three. The differences are real, reflecting genuine settlement differences visible in any comparison of Airwallex and Wise or across the cross-border payout API field. A product that wants more than one of them needs its own vocabulary first.


Where does coupling actually cost money?

A provider change becomes a product rewrite. Six months in, a fintech needs a second provider for a new market. Engineering finds the first provider’s identifiers serving as internal account IDs, its statuses driving the interface, and its settlement references load-bearing in reconciliation. The team has to change the data model, the state machine, dashboards, notifications, and support procedures.

Reconciliation becomes an operational patchwork. Take the Wise reversal sequence. A transfer reaches outgoing_payment_sent, the product displays “Completed,” the customer is notified. Weeks later it bounces back and is refunded. If the ledger, the customer-facing status, and the provider report each define completion differently, operations reconstructs what happened from three systems. No reconciliation software fixes that, because the tool cannot invent a shared key the product never created.

Separation does not make provider addition free. Where every provider sits behind an adapter by design, connecting one an adapter already supports takes a few days to a week: configuration, routing, jurisdiction and currency checks, operational setup, QA. Building a new adapter takes several weeks, spanning backend development, status mapping and webhooks, orchestration and routing, reconciliation tooling, UI and payment form changes, new account detail formats, error handling, and testing.

That list contains customer-facing work. New account detail formats mean new beneficiary fields, which mean interface changes. That is a corridor difference, not provider leakage, and no architecture removes it. What separation removes is the other kind: new statuses, rewritten copy, schema migrations, and runbook edits caused purely by a provider describing the same event in different words.


What separation actually matters?

The goal is not pretending providers are identical. They are not, and the differences are frequently why you chose one. The goal is a stable product contract with provider behavior contained behind it. Four layers do the work.

Product-facing contracts. The product initiates actions using its own objects. A payment request carries a customer, source account, beneficiary, amount, currency, and purpose. It should not require the customer application to know which provider field represents each concept, or which provider will execute it.

Workflow orchestration. This layer decides which route handles an action and how the product responds to asynchronous outcomes. It owns retries, idempotency, fallbacks, manual review, and exception routing, which is the shape of Framnex’s connector and orchestration model. It is also where whether you need a payment orchestration platform becomes answerable, since the answer depends on how much routing and fallback your roadmap requires.

Provider adapters. An adapter translates the contract into the provider’s API and back, owning field mapping, authentication, references, error interpretation, and webhook validation. Real capability differences stay explicit here rather than hidden behind a common interface that quietly lies. Wise’s guidance on unrecognized failure codes belongs here too: the adapter is the only place that should ever see a code it does not recognize.

A product-owned financial record. The product needs its own traceable record of financial events, connected to the orchestration and adapter layers. Provider reports stay essential but get reconciled against an internal transaction and ledger model rather than treated as the only readable source. An internal lifecycle might run received, pending_review, processing, completed, failed, returned, with the original provider status retained for audit. Since Stripe documents a paid payout that can become failed, that model must treat completed as revocable.


What it looks like when the separation already exists

A reference point from a Framnex engagement. A fintech building a B2B payments product needed SWIFT payments in selected jurisdictions through a new BaaS provider. Framnex built a new adapter and connected it to the platform’s existing payment architecture and operational workflows.

The integration took approximately two weeks, and the number matters only because of its cause: core payment flows, transaction statuses, and operational scenarios were already separated from individual providers, so the work stayed inside the adapter and orchestration layers. The client added a payment channel without substantial changes to its customer interface or core product logic.

That is not a comparison against a tightly coupled build of the same integration, because no such counterfactual exists here. It is the cost of a new route in a product that had already done the separation work, which is the benchmark worth holding your own architecture against. The same shape applies whenever a financial action is added to an existing customer journey, which is what Framnex’s embedded finance model is organized around.


How do you reduce coupling without a rewrite?

Coupling comes out one workflow at a time.

Start with a flow that hurts, such as business onboarding or outbound payouts. Document the happy path and the five most common exceptions, because the exceptions are where the coupling lives. Then trace where provider identifiers, statuses, and error codes appear. Look past the backend: grep the repository for the provider’s status strings, then ask finance what they open on the first of the month.

Define the smallest canonical model that works, covering the product you operate and the next route you realistically expect. Move translation into the adapter, then run both views in parallel during migration and compare the new internal lifecycle against provider reports and the existing process. The mismatches are the point of the exercise.

Then apply the Second Route Test. The question is not whether the first adapter works. It is whether a second provider can be connected without changing your status vocabulary, notification copy, schema, or support runbook. New beneficiary fields for a new corridor are legitimate. New internal statuses because a provider uses different words for the same event are not. This is the only test that cannot be passed on paper, and it belongs in due diligence alongside the criteria in the FintechSpecs vendor evaluation framework.


When is provider independence not worth building?

Provider independence becomes expensive when pursued without a commercial reason. No team should build a universal orchestration platform before validating its first product and first provider.

One market, one stable provider, no near-term expansion: a clean adapter and an internal transaction model is enough, and more is speculative engineering. Multiple markets, fallback routes, or several products on the same rails: orchestration and canonical states are easier to justify early, since the alternative is paying for them later at a worse rate.

The honest version is a forecast, not a principle. If you cannot name the second provider you expect to add and roughly when, you are probably building too much. If you can, you are probably building too little. Where this sits is clearer against a full fintech infrastructure stack map.


Frequently asked questions

How long does it take to add a new payment provider?

It depends on whether an adapter already exists. Where providers sit behind adapters by design, connecting a supported provider is typically a few days to a week of configuration, routing, jurisdiction and currency checks, and QA. Building a new adapter usually takes several weeks. In one Framnex engagement adding SWIFT payments through a new BaaS provider, the integration took roughly two weeks because the product side was already separated.

How do you know if your product is too coupled to one provider?

Run the Second Route Test. Specify connecting a second provider and list every change required. If the list includes new customer-facing statuses, notification copy changes, schema migrations, or runbook edits, the product is coupled. New beneficiary fields for a new corridor do not count, since those are real market differences.

Does a completed payment status mean the beneficiary received the money?

Usually not. Across major providers, the terminal happy-path state means the payment was dispatched to the receiving bank or network, not that the beneficiary account was credited. Reversals can arrive weeks later. Products that treat dispatch as delivery will show customers a completed payment that later reverses, which is a reconciliation problem rather than a display bug.


The decision is really about product ownership

When provider logic sits behind stable contracts, orchestration, adapters, and a product-owned financial record, a company can change infrastructure without redesigning the customer experience. Expansion becomes a controlled integration project rather than a product rewrite.

So the useful question at integration time is not how quickly you can connect a provider. It is which parts of your product will depend on it afterward. That question exposes the hidden cost while it is still cheap to avoid.

Mike Novikov
Mike Novikov

Mike Novikov is CTO at Framnex, where he leads platform architecture and engineering. He works on modular financial infrastructure, provider integrations, and the operational workflows required to launch and scale banking, payments, and embedded finance products.