Single gateway: simpler, lower maintenance, appropriate for most businesses under NGN 100M/month with a single primary market. Multi-gateway: add a second when you need failover (primary gateway outage affects revenue), market coverage (second gateway covers a country the first does not), or routing optimization (direct bank integrations for high volume). Do not add a second gateway because it "seems safer" — the operational complexity is real and the benefit only materializes if the first gateway fails, which should be rare.
| Dimension | Single Gateway | Multi-Gateway |
|---|---|---|
| Integration complexity | One set of APIs, one webhook handler, one set of credentials | N times the complexity; requires abstraction layer |
| Reconciliation | One settlement report, one transaction log to reconcile | Multiple reports, cross-gateway reference mapping required |
| Failover | If gateway is down, payments fail | Route to secondary on primary outage — requires health monitoring |
| Country coverage | Limited to primary gateway's markets | Route by country to the best gateway for each |
| Stored cards/subscriptions | Token lives on one gateway | Tokens are not portable — each gateway stores its own |
| Maintenance burden | One gateway to update when APIs change | All gateways need updates when any changes |
| When to use | Starting out, single market, under NGN 100M/month | Scale, multi-market, or demonstrated failover need |
// Multi-gateway routing example with health checking
class PaymentRouter {
constructor(gateways) {
this.gateways = gateways; // [{ name: 'paystack', client, healthy: true }, ...]
}
async route(country, amount, channel) {
// Filter to gateways that support this country + channel
var eligible = this.gateways.filter(g =>
g.healthy && g.countries.includes(country) && g.channels.includes(channel)
);
if (!eligible.length) throw new Error('No healthy gateway available for ' + country + '/' + channel);
// Simple round-robin or primary-first selection
return eligible[0];
}
async healthCheck() {
for (var g of this.gateways) {
try {
var res = await fetch(g.healthUrl, { timeout: 3000 });
g.healthy = res.ok;
} catch {
g.healthy = false;
}
}
}
}
See building a payment provider abstraction layer before adding a second gateway.
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course