A payment system has one job: move money exactly once. Not zero times, not twice. The trouble is that every step involves a network call to someone else (a bank, a card network, a UPI switch), and any of those calls can time out without telling you whether it worked. In this lab you'll design a payment gateway from a blank page, modelled on a product like Razorpay. You'll spend most of your time on the cases where you don't know what happened.
The brief
A payment gateway sits between merchants (shops, apps, websites) and the banking system. A merchant's checkout calls the gateway to collect money from a customer by card, UPI, netbanking or wallet. The gateway talks to banks and networks, tells the merchant whether it worked, and later pays the collected money out to the merchant's bank account (settlement).
In scope:
- Creating and processing a payment.
- Making retries safe for merchants and for our own calls to banks.
- Recording every money movement in a ledger.
- Telling merchants about results (webhooks).
- Reconciliation: matching our records against the banks' records.
Out of scope:
- Fraud and risk scoring (assume a service says yes or no).
- Card storage and PCI scope (assume a separate tokenisation vault).
- Merchant onboarding and KYC.
- Subscriptions, payment links and other products built on top.
Requirements
Functional
- A merchant creates an order for an amount, then the customer pays it with a chosen method.
- The merchant can query a payment's status at any time.
- The merchant receives a webhook when a payment succeeds or fails.
- Captured payments are settled to the merchant (minus fees) on a schedule, usually T+1 or T+2.
- Merchants can issue full or partial refunds.
Non-functional
- Exactly once, as the user sees it. A customer is never charged twice for one order. A merchant never gets paid twice for one payment.
- Never lose money or a record of it. Every rupee is accounted for: every debit has a matching credit, and our books match the banks' books.
- Correct before fast. A slow "processing" is acceptable; a wrong "failed" for a payment that succeeded is not.
- Available: checkout is revenue for thousands of merchants. Target 99.99% for the payment API.
- Auditable: every state change is recorded and nothing is edited in place.