If adding provider two costs what provider one cost, the problem isn’t the provider.

Every platform eventually needs a second processor. The reasons are boring: an outage with nothing to fail over to, a big partner who insists on their own, pricing that moves, a payment type your current provider doesn’t reach well.
So someone scopes it, and the number comes back looking a lot like the original integration. Six weeks minimum, touching most of the payments code. Everyone quietly agrees to revisit it next year.
That estimate is usually correct — because of a decision made two years earlier.
Why the second one costs as much as the first

Not because payment providers are hard. Because the first one was never given a boundary, so it soaked into everything. You can check this in twenty minutes. Look for:
- Provider IDs used as your primary keys. The charge ID is the payment record. There is no payment record.
- Provider status strings in your database and your UI. Somewhere there’s a switch statement on the provider’s vocabulary and a template rendering it to a customer.
- Business logic inside webhook handlers. The handler doesn’t just record an event, it decides things — who gets access, which email goes out, what hits the ledger.
- Reconciliation written against one file format. The settlement parser and the matching logic are the same function.
If you find those, adding a provider means editing your business logic, which means regression-testing your business logic. That’s where the six weeks comes from.
The boundary

The fix isn’t exotic. You need your own model of a payment, and the providers translate into it.
Your own IDs, your own states. A payment is a row you created, with an ID you generated, in a state you defined — initiated, submitted, settled, returned, failed. Five states, six at most, each one meaningful to your business. The provider’s forty statuses map into yours, never the other way around.
Adapters at the edge. Each provider gets an adapter with two jobs: turn your intent into their API call, turn their events into your state changes. It’s the only code in the system that knows the provider’s vocabulary.
One reconciliation engine, per-provider parsers. Matching, exception handling, and how long an unmatched item has been open — none of that should know which provider it came from. Each provider gets a small parser that turns its settlement file into the same rows, in your format. Teams skip this, and it’s the piece that makes provider two land on time.
Every record knows which provider it came from. Ledger entries, settlement rows, exceptions, reports. You’ll be asked “what did we run through each one last month” within a week of going live. Answer it with a column, not a migration.
Things that don’t move

Three that bite:
- Refunds go back to the processor that took the money. Original payments stay with the original provider forever, so your model has to remember which one, per payment, permanently.
- Stored mandates and credentials usually don’t transfer. Pre-authorized debit agreements, tokens, details on file — assume they stay put unless both providers say otherwise in writing. Moving existing recurring payers is a separate decision with its own consent questions.
- Your reporting doubles. Two settlement cadences, two cutoff times, two return code vocabularies. Translate every provider’s return codes into your own list at the edge, or your ops team ends up learning both.
Routing: keep it dumb

There’s a strong pull toward building a routing engine — weights, failover rules, cost optimization, a config UI. Don’t, not on day one. Start with a rule you can say in one sentence: “new Canadian accounts go to provider B, everything else stays on A.” A function, not a rules engine. Three months of actually running two providers will teach you more than anything you can design up front. An engine built before that is a guess with a config screen.
What it looks like when it works

One platform we worked with had provider concepts in about forty files. Most of the project was pulling payments behind a boundary and re-pointing the existing provider at it — no behavior change, so it shipped in safe pieces. The second provider itself was an adapter and a settlement parser, live in under two weeks.
Most of the cost was paying down the first integration. That bill is fixed. You pay it once — on provider two or provider three — and every provider after that is the adapter and the parser.
The test

You have a boundary if you can add a provider by writing one adapter and one settlement parser, and touching zero business logic. If you can’t answer that with a yes, the first thing to scope isn’t the second processor.
FAQ
Why does adding a second payment processor cost as much as the first? Because the first provider was never given a boundary. Provider IDs became your primary keys, their status strings landed in your UI, business logic sat inside webhook handlers, and reconciliation was written against one file format. Adding a provider then means editing — and retesting — your business logic.
What is a payment boundary?
Your own model of a payment: IDs you generate, states you define (initiated, submitted, settled, returned, failed), adapters at the edge that translate each provider into that model, and one reconciliation engine with per-provider parsers. The provider’s vocabulary never becomes yours.
How do you know you have a real boundary? You can add a provider by writing one adapter and one settlement parser, and touching zero business logic. If you can’t answer yes, scope the boundary first — not the second processor.
What doesn’t move when you add a second processor? Refunds go back to the processor that took the money. Stored mandates and credentials usually don’t transfer. Reporting doubles until you translate return codes into your own list at the edge.
What we do and what stays yours
Futurify builds software. We don’t hold funds, move money, or act as a processor. Your provider agreements and your pricing stay yours. We build the layer that means adding one isn’t a project.
Next step
Send us the provider you’re adding and the date — hello@futurify.io. If you can, grep for the provider’s name in your codebase first and tell us the file count. Under ten and you’re adding a provider. Over thirty and you’re paying down the first integration before you can touch the second — that’s the conversation to have.