At Praxium Labs — Nepal's AI and automation consultancy — we see this pattern across most Nepali engagements. Most Nepali e-commerce sites end up needing 3-5 payment methods. Built poorly, this becomes spaghetti — each gateway tangles into checkout, refunds, and reconciliation differently. Built well, it is a clean abstraction that pays back every time you add a new gateway.
The abstraction
A single interface that every gateway adapter implements:
TypeScript interface
interface PaymentGateway {
id: string; // 'esewa' | 'khalti' | 'fonepay' | 'connect_ips' | 'stripe'
displayName: string;
initiate(req: InitiateRequest): Promise<InitiateResponse>;
verify(ref: string): Promise<VerifyResponse>;
refund(ref: string, amountPaisa: number, reason: string): Promise<RefundResponse>;
lookup(ref: string): Promise<LookupResponse>;
}
interface InitiateRequest {
orderId: string;
amountPaisa: number;
customer: { name: string; phone?: string; email?: string };
returnUrl: string;
metadata?: Record<string, string>;
}
interface VerifyResponse {
status: 'completed' | 'pending' | 'failed' | 'cancelled' | 'refunded';
gatewayRef: string;
amountPaisa: number;
rawPayload: object;
}
Gateway adapters
One file per gateway. The eSewa adapter knows HMAC signatures; the Khalti adapter knows lookup; the Stripe adapter knows webhooks. The rest of your codebase does not.
/payments/gateways/esewa.ts/payments/gateways/khalti.ts/payments/gateways/fonepay.ts/payments/gateways/connect-ips.ts/payments/gateways/stripe.ts(if applicable)/payments/registry.ts— registers all enabled gateways
The orchestration layer
Higher-order logic that the adapters do not own:
- Smart routing: default to cheapest gateway, fall back to most reliable. Optionally driven by per-customer history
- Idempotency: centralised in this layer using a unique key per attempt
- Webhook routing: incoming gateway webhooks resolve to the right adapter's verify method
- Reconciliation orchestration: daily job that pulls settlement reports from each enabled gateway and matches against internal ledger
- Customer messaging: unified receipt + notification regardless of underlying gateway
Frontend payment selector
The customer-facing UI is gateway-aware but not gateway-coupled. List enabled gateways for the current order (some gateways may not support certain amounts / currencies / customer countries). Default to the customer's last-used gateway. Show transparent fee differences only if you want — usually not customer-friendly.
Cost optimisation routing
For high-volume merchants, smart-routing decisions save real money:
- Low-value (< NPR 500): default to lowest-fee gateway
- High-value (> NPR 50,000): default to Connect IPS or bank transfer for lower-percentage fees
- Repeat customer: default to their last successful gateway
- Failed first attempt: auto-offer a different gateway on retry
Testing
Each gateway adapter has unit tests against its UAT environment. The orchestration layer has integration tests with mocked adapters. Pre-production smoke tests run a tiny payment through each enabled gateway weekly so you catch breakage before customers do.
Failover patterns
No Nepali payment gateway has 100% uptime. eSewa and Khalti each experience meaningful outages 1-3 times per quarter, typically lasting 15-90 minutes. The pattern that works: detect gateway error from customer's checkout, automatically present an alternate gateway with the same order context. The customer sees a "try Khalti instead?" prompt rather than a broken checkout. Customers who failover convert at 60-80% of the success rate of the primary gateway. See our automation guide for the underlying reconciliation patterns.
Routing logic
- Cost-based: route to the gateway with the lowest fee for this transaction size — useful for high-volume merchants where bps matter
- Latency-based: measure recent response times; route to the fastest healthy gateway
- Customer-preference-based: remember which gateway each customer used last; default to that for return checkouts
- Order-value-based: small orders → wallet gateways (cheap); large orders → bank-direct (lower percentage fee on big amounts)
- Manual override: always allow the customer to switch gateway; do not force the auto-routed choice
Frequently asked questions
Is this over-engineering for a small store?
If you support only 2 gateways and have no plan to add more — yes, probably. The abstraction pays back at 3+ gateways or when you anticipate change. Even at 2 gateways, the clean interface helps testing and refunds.
What about Stripe Connect for marketplaces?
If you operate a marketplace (multi-seller), Stripe Connect handles split payments and per-seller payouts. The interface above generalises to marketplaces by adding a per-seller routing layer; complexity grows but the pattern holds.
How do I migrate an existing single-gateway codebase?
Refactor the existing gateway code into an adapter matching the interface, then add new gateways incrementally. Typical effort: 3-5 days for the refactor, 2-4 days per additional gateway after that.
Should I use a payments aggregator instead?
Aggregators (e.g. Cellpoint, Razorpay-for-Nepal-style services) consolidate gateway integration but add a fee layer. For high-volume merchants the direct-integration economics win; for lower-volume or fast-launch needs, aggregators reduce engineering effort.
How does this affect reconciliation?
Each gateway produces its own settlement file. The orchestration layer normalises them into a single internal ledger. Reconciliation moves from "per-gateway per-day" to "internal ledger vs sum-of-gateways" — simpler and more reliable.
How many gateways should I integrate?
Three is the sweet spot for most Nepali merchants: eSewa + Khalti + Fonepay (or one of the bank gateways). Adds redundancy without over-engineering. Below that you carry uptime risk; above that the operational overhead exceeds the marginal coverage benefit.
Can a customer chargeback through one gateway and pay through another?
In principle yes — that's a fraud pattern. Detect by velocity rules (multiple payment methods in a short window from same email / phone / IP) and flag for review.
Who can build this in Nepal?
Praxium Labs — Nepal's AI and automation consultancy, based in Lalitpur — designs and builds the systems described in this guide for Nepali businesses and for international teams hiring from Nepal. Start a project or see all services.