Skip to main content

This week, the UK Government Digital Service quietly completed one of the most significant payment infrastructure migrations in European public sector history. GOV.UK Pay — the platform processing over £9.2 billion across 137.5 million transactions since 2016 — replaced Stripe with Dutch processor Adyen for roughly 1,000 services across local authorities, police forces, and armed forces units.

The remarkable part? Not a single service experienced downtime. Not one paying user noticed the difference.

That is not luck. That is architecture.

TL;DR

  • GOV.UK Pay migrated 1,000 services from Stripe to Adyen without disruption — because they built a provider-agnostic abstraction layer from day one
  • Most businesses wire their payment provider directly into their application code, creating a single point of failure that is expensive and risky to change
  • Payment provider lock-in is not just a technical problem — it is a commercial one, affecting your negotiating power, compliance posture, and ability to adopt new payment methods
  • Building a payment abstraction layer costs more upfront but pays for itself the first time you need to switch, renegotiate, or add a new payment method
  • The trend towards open banking and pay-by-bank means your payment architecture needs to be more flexible than ever

Why This Matters Beyond Government

If you are building a SaaS product, an e-commerce platform, or any application that takes payments, your payment provider is almost certainly a single point of failure. Not in the sense that it might go down — Stripe, Adyen, and their peers have excellent uptime. In the sense that switching away from it would be a painful, expensive, months-long engineering project.

Most development teams treat payment integration as a one-time decision. You pick Stripe because the developer experience is excellent (it is), you wire in the API, and you move on to the next feature. Six months later, your checkout flow, subscription logic, webhook handlers, refund processes, and reconciliation scripts are all tightly coupled to a single vendor’s API.

You have not integrated a payment provider. You have married one.

The Real Cost of Payment Provider Lock-In

Lock-in sounds abstract until you hit one of these situations:

Your provider raises fees. Stripe’s standard rate of 1.5% + 20p per transaction is competitive — until it is not. If your transaction volume grows and you want to negotiate enterprise rates, your leverage depends entirely on whether your provider believes you could actually leave. If your codebase says otherwise, they know it too.

Regulation shifts. The EU’s PSD3 directive, expected to take full effect by 2027, will strengthen requirements around payment data sovereignty and open banking access. If your payment logic is hardcoded to one provider’s API surface, adapting to new compliance requirements means rewriting, not configuring.

A better option emerges. GOV.UK’s move to Adyen was partly driven by the ability to offer “pay by bank” — direct bank-to-bank transfers via open banking that skip card networks entirely. For government services, this means lower fees and reduced fraud. For your business, similar options are emerging that your current tight coupling prevents you from offering.

Your provider has an incident in your region. In March 2025, Stripe experienced a significant outage affecting European merchants for several hours. If your payment flow has no fallback path, your revenue stops when your provider stops.

What GOV.UK Got Right

The GOV.UK Pay team designed their platform with provider abstraction as a first-class concern. Here is what that looks like in practice:

A clean internal API. Services interact with GOV.UK Pay through a standardised interface. They do not know — and do not need to know — whether Stripe, Adyen, or WorldPay is processing their transaction. The provider is an implementation detail, not a dependency.

Centralised compliance. Know Your Customer (KYC) requirements, PCI DSS compliance, and fraud detection are handled at the platform layer. Individual services are not responsible for understanding the regulatory differences between providers.

Multi-provider by design. Even after the Adyen migration, WorldPay continues handling central government and NHS payments. This is not a transitional state — it is the architecture. Different providers for different use cases, all behind the same interface.

The result: a £25.3 million, three-year contract migration affecting 70% of the platform’s organisations, completed without a single service needing to change its integration code.

Building Your Own Payment Abstraction Layer

You do not need to be the UK government to benefit from this pattern. Here is a practical approach for development teams at any scale:

1. Define Your Payment Interface

Start by defining what your application actually needs from a payment provider. For most SaaS products, it is surprisingly narrow:

  • Create a payment intent / charge
  • Confirm payment
  • Issue a refund
  • Create and manage subscriptions
  • Handle webhooks for asynchronous events
  • Store and retrieve payment methods

Define these as interfaces in your codebase. Your application logic calls these interfaces — never the provider SDK directly.

2. Implement Provider Adapters

Each payment provider becomes an adapter that implements your interface. Your Stripe adapter translates your internal createCharge() call into Stripe’s paymentIntents.create(). An Adyen adapter would translate the same call into Adyen’s /payments endpoint.

You only need one adapter to start. The value is not in having multiple providers on day one — it is in ensuring you can add one on day thirty without rewriting your checkout flow.

3. Normalise Webhook Events

This is where most abstraction attempts fall apart. Every provider has its own webhook format, event naming, and delivery guarantees. Build a webhook normalisation layer that translates provider-specific events into your internal event format: payment.succeeded, payment.failed, subscription.renewed, refund.completed.

Store the raw provider payload alongside your normalised event for debugging and reconciliation.

4. Externalise Configuration

Provider selection, API keys, and routing rules should live in configuration, not code. This enables per-region provider routing (Adyen for EU, Stripe for US), A/B testing of checkout flows, and graceful failover if a provider experiences issues.

The Open Banking Factor

GOV.UK’s migration was not just about switching providers — it was about accessing new payment rails. The “pay by bank” feature that Adyen enables uses open banking APIs to allow direct bank-to-bank transfers. No card details. No card network fees. Lower fraud rates.

This is not a government-only trend. Open banking adoption across Europe is accelerating, and PSD3 will make it even more accessible. Businesses that have built flexible payment architectures can offer pay-by-bank alongside traditional card payments. Businesses locked into a single provider’s API can only offer what that provider supports.

The payment landscape is diversifying — cards, open banking, digital wallets, and potentially stablecoins for B2B payments. Your architecture needs to accommodate payment methods that do not exist yet.

When to Invest in Abstraction

Not every application needs a full payment abstraction layer on day one. If you are building an MVP and processing fewer than a thousand transactions a month, direct Stripe integration is absolutely fine. Ship the product, find the market.

But consider investing in abstraction when:

  • You are processing over £50,000 per month and fees become a material cost
  • You are expanding into new markets with different payment preferences
  • Your provider contract is coming up for renewal and you want negotiating leverage
  • You need to support payment methods your current provider does not offer
  • Regulatory requirements are pushing you towards specific providers for specific regions

The Bigger Lesson

The GOV.UK Pay story is not really about payments. It is about a principle that applies to every critical third-party dependency in your stack: build for switchability.

Your email provider, your authentication service, your cloud platform, your AI model provider — every vendor relationship should be mediated by an interface you control. The cost of abstraction is a few extra days of engineering upfront. The cost of lock-in is measured in months of migration work, lost negotiating power, and missed opportunities.

GOV.UK proved this week that you can migrate 1,000 services to a new payment provider without breaking a single one. The question is: could your business do the same?

Need Help Building for Switchability?

At REPTILEHAUS, we help businesses design payment architectures, API integrations, and SaaS platforms that are built to last — not locked to a single vendor. Whether you are planning a payment infrastructure overhaul, evaluating providers, or building a new product and want to get the architecture right from the start, get in touch.

📷 Photo by Albert Stoynov on Unsplash