Payments
Taking money is the part of commerce with the least tolerance for bugs. The payment layer is built around three principles: never double-charge, always reconcile, and survive a flaky gateway.
Two gateways
The platform integrates two payment providers behind a common surface:
- Razorpay — primary Indian gateway: order creation, card/UPI payments, saved payment methods, payment links.
- PayU — a second gateway for redundancy and coverage.
Each is wrapped in its own service (RazorpayPaymentService,
PayuPaymentService) so the rest of the app talks to payments through a stable
interface rather than a vendor SDK.
Never double-charge: idempotency
Every order-creation call carries an idempotency key. If a request is
retried — because the network blipped, or the shopper double-clicked — the
gateway returns the existing order rather than creating a second one.
CheckoutIdempotencyService enforces the same guarantee on the app side.
Survive a flaky gateway: circuit breaker
Payment services include PaymentCircuitBreaker. When a gateway starts
failing or timing out, the breaker opens — subsequent calls fail fast
instead of piling up threads against a dead endpoint — then probes for recovery
before closing again. A degraded gateway becomes a clear, fast error instead of
a cascading outage.
Always reconcile
A payment is not “done” when the shopper sees a success page. Money settles later, asynchronously, and the platform’s records must match the gateway’s:
- Webhooks —
RazorpayWebhookServiceverifies signatures and processes payment, refund, and settlement events. - Settlement sync —
RazorpaySettlementSyncServicepulls settlement batches so payouts can be traced to underlying orders. - Refund sync —
RazorpayRefundSyncServicekeeps refund state aligned between the app and the gateway. - Reconciliation —
RazorpayReconciliationServiceruns end-to-end checks, recording results inreconciliation_runsand flagging mismatches.
Payouts to vendors
Because the platform is multi-vendor,
settlement money has to be split. PayoutCalculationService computes what each
vendor is owed from the orders that settled, and payouts are tracked as
first-class Payout records.
Key files
| Concern | Files |
|---|---|
| Models | PaymentIntent, RazorpaySettlement, Refund, Payout, SavedPaymentMethod, ReconciliationRun |
| Gateways | RazorpayPaymentService, PayuPaymentService, PaymentGatewayService |
| Reconciliation | RazorpayWebhookService, RazorpaySettlementSyncService, RazorpayRefundSyncService, RazorpayReconciliationService |
| Resilience | PaymentCircuitBreaker, CheckoutIdempotencyService, RazorpayRateLimiter |