Skip to main content
Payment gateway migration without rewriting your checkout
paymentspayment-infrastructurecheckout+2

Payment gateway migration without rewriting your checkout

Payment gateway migration turns into a rebuild when your checkout was built for one vendor. Where to draw the line so the next swap is a scoped job.

Near the end of a first call, usually after the interesting part, someone asks how hard it would be to switch processors later. It gets asked lightly, the way you ask about a warranty. It is the most expensive question on the call.

The trigger is rarely one you picked: an acquisition, an exit from your market, a reprice at renewal, a frozen account while a risk team reviews a volume spike. The question is the same either way. How long until we can take money through someone else? Nobody knows until somebody looks, and what comes back is a project rather than a change request. That has little to do with how much the two processors differ. It comes from a checkout written as though there would only ever be one, and the cheap moment to write it differently is before any code exists.

Why payment gateway migration turns into a rebuild

It starts with the SDK in the checkout controller, which is fine. Then the webhook handler that sets order status straight from the processor’s event names. Then the refund process, which is an ops person logging into the vendor’s dashboard, because nobody ever built the button.

Each was the fastest move available that week. Added up, the processor’s data model has become your data model, and changing processors means editing all of it while real money runs through it.

The clearest symptom is in your primary keys. If a table identifies a customer, a subscription or an invoice by an ID a payment company issued, that record cannot exist without that company. Search your schema for the processor’s ID format and count the hits sitting in a primary key or a joined column. That count is the shape of the migration.

How to avoid payment processor lock-in in your checkout

Draw a line. Below it, one adapter per processor. Above it, product code that speaks only your own vocabulary: your order IDs, your payment statuses, your subscription states, your refund reasons.

The interface at that line is smaller than people expect. Start a payment. Capture it. Refund all or part of it. Store a card against a customer. Start, change, pause and cancel a subscription. Turn a webhook into one of your own domain events. That is the whole surface for most products, and writing it down is worth an afternoon: on paper you can see which vendor-specific features you have taken a dependency on, and decide whether each earns it.

A universal abstraction over everything every gateway can do is a product in its own right, maintained forever. The useful version is narrow. Cover the operations you actually call. Where you genuinely need something vendor-shaped, like hosted card fields or a risk API, put it in a named directory and accept it gets rewritten if you move. Untouched code plus one known slice is a scope somebody can quote. Without the boundary, the estimate arrives after the archaeology.

Most of a custom payment gateway integration is this part rather than the checkout. Taking a card payment works in an afternoon.

Keep your own payment ledger

Write every payment event to your own database as it happens: charge, authorization, capture, refund, retry, dispute, payout, with the raw webhook payload stored alongside your interpretation of it. Handlers have to be safe to run twice, because gateways redeliver. A gap raises an alert.

This pays for itself long before any migration, on the month-end where the gateway dashboard and the bank disagree and something has to say which one is wrong. It is what keeps any integration between two systems honest: reconcile on a schedule, and report what disagrees.

Dashboard access at the old provider ends when the relationship does, while dispute evidence, chargeback history and tax records outlive it by years. You can export, obviously. An export sitting in a bucket is not a system anyone can query at audit time. During cut-over both providers are live, and only the ledger holds both event streams in one schema.

Can you move stored cards to a new payment gateway?

For a subscription business, this is the migration. Everything above the line is your own code. This part needs two other companies to cooperate.

A card token issued by one gateway means nothing at another. Whether a processor will hand your encrypted card data to a competitor’s PCI-audited vault has a per-provider answer, and a yes comes on their timetable rather than as an API call you schedule. The fallbacks are worse: ask your customers to re-enter card details and lose a slice of active subscribers doing it, or keep both providers live while the old cards age out. Our cost guide assumes the second by default, because card-on-file tokens do not travel between providers.

If you bill recurring in India, ask about mandates separately: get it in writing whether a UPI autopay mandate or an e-mandate survives a change of processor. Ask all of this during procurement, while you still have leverage. How does a card vault export work, and how long has it taken other merchants? A vague answer makes that provider a one-way door; price it accordingly.

What the boundary costs up front

Choosing a gateway against your real markets and settlement terms takes three to five days. A sandbox build of checkout, webhooks and the database side takes one to two weeks, then live activation about a week. Our payment gateway integration cost guide puts that work, a single-gateway checkout, in Tier 1 at ₹1L – ₹1.5L, indicative for scoping rather than a quote. The seam lives inside that sandbox build: days of structuring, not a phase added to the plan.

Subscriptions and failed-card recovery move you up the tiers, and so does routing across markets. We scope that in paid discovery and quote a fixed price; guessing at payments work under an hourly model is how these projects end up half-finished. Running two providers live at once costs more than the configuration change it sounds like: two sets of webhooks, two reconciliation jobs, two fraud configurations, and two sets of behavior to learn at two in the morning. The payment aggregator versus direct gateway comparison covers the rest of that decision.

Retrofitting the boundary later is the expensive version, because by then five or six systems read the processor’s IDs. Stop the spread before you fix the history: put the adapter in, route new code through it, and issue your own IDs for anything created from today. Backfill old records in their own time, or leave them where the money has settled.

Here is the trade-off I would take. The checkout ignores some of what the vendor is selling you: the ready-made screens, and the subscription objects it would happily be the system of record for. You maintain a translation layer that earns nothing in an ordinary week, and you agree up front that one named directory gets rewritten if you ever move. What that buys is an answer to the question at the end of the first call: a number of weeks, at a price, with the risky part named. It is worth most on the day someone else picks the timing.

Have a project in mind?

Fixed price after a paid discovery — no hourly billing. A real engineer reads every enquiry, and we reply within 24 hours.