Design Razorpay UPI Payment System: Interview Guide
Razorpay processes 250 million transactions per month for 10 million businesses across India, routing through UPI rails that handle 15 billion monthly transactions at peak.
Designing Razorpay is the India-specific payment problem: you have to talk about UPI rails, NPCI integration, the differences between Cards, Net Banking, UPI, and wallets, and the regulatory environment (RBI, tokenization mandates). It tests whether you understand what makes Indian payments uniquely demanding: collect requests, virtual payment addresses, and the 60+ banks that all need to settle.
Asked at: Commonly asked at Razorpay, PhonePe, Paytm, Cred, Cashfree, Pine Labs, BharatPe, and any Indian fintech. Also asked at FAANG India interviews for context-specific depth.
Why this question is asked
Design Razorpay forces candidates to handle a payment system with multiple payment-method rails (cards plus UPI plus net banking plus wallets), each with different protocols and reliability profiles. UPI alone is its own thing: it is push-based, has collect requests, and depends on NPCI as a central switch. Bonus credit for talking about reconciliation across banks and the 24x7 nature of UPI versus the batch nature of card settlement.
Requirements
Always clarify these in the first 5 minutes of the interview. Do not start drawing boxes until both lists are agreed.
Functional requirements
- Merchants integrate via REST API to accept payments
- Support cards, UPI, net banking, wallets, EMI in a single flow
- UPI collect request: merchant initiates, customer approves in their UPI app
- UPI intent flow: customer is redirected into a UPI app
- Real-time webhook notification on success or failure
- Refunds (full and partial) with appropriate rail routing
- Subscription and auto-debit support (e-mandates on UPI and cards)
Non-functional requirements
- 99.99% API availability
- Sub-second checkout response (UPI status callbacks are async)
- Strong consistency on transaction state and idempotency
- PCI DSS compliance for card flows; NPCI compliance for UPI
- Settlement to merchant within 1 to 2 business days
- Reconciliation against bank statements within 24 hours
Back-of-envelope scale estimates
Show your math. Pulling numbers from thin air signals you have not thought about the load.
Transactions per month
250M
Public Razorpay reporting. Used to size transaction storage and processor throughput.
Transactions per second (peak)
5K
Average ~100 per second, peak during sale events (Big Billion Days clones) ~50x.
UPI share of transactions
70%
Public Indian payment industry data: UPI dominates volume share over cards in India.
Webhook deliveries per day
30M
Multiple events per transaction (initiated, succeeded, settled). Retries on failure amplify further.
Settlement volume per month
INR 1T
Public Razorpay TPV reporting in INR. Drives ledger storage and reconciliation jobs.
High-level architecture
Merchant calls the Razorpay Public API to create an order. The API Gateway authenticates the merchant API key and routes to the Order Service. The Order Service writes a pending order, idempotent by order_receipt, and returns a payment session token. The customer is redirected to a Razorpay-hosted checkout (or an SDK-rendered iframe), where they pick a payment method. On selection, the Payment Service routes to the appropriate rail. UPI: a request goes to the UPI Adapter, which calls NPCI to initiate a collect request or generate an intent URL. The customer approves in their UPI app, and NPCI fires an async callback to Razorpay. Cards: the Card Adapter calls the issuer or acquirer (HDFC, ICICI, Axis) for authorization, possibly via 3D Secure 2.0. The Transaction Service updates state on each callback and emits an event. The Settlement Service runs daily batches that compute merchant balances and initiate bank transfers. Reconciliation Service compares Razorpay's ledger against bank statements every night.
In a real interview, sketch this on the whiteboard before diving into any single box.
Core components
Walk through each service. The interviewer wants to hear what each one owns, not just the names.
Public API Gateway
Authenticates merchant API keys, enforces rate limits, exposes /v1/orders, /v1/payments, /v1/refunds. Logs every request.
Order and Payment Service
Owns order and payment lifecycle. Idempotent on order_receipt (merchant-supplied) and on payment_id. Writes to sharded MySQL.
UPI Adapter
Integrates with NPCI over the UPI APIs. Handles collect requests, intent URL generation, transaction status polling, and async callbacks. Implements the UPI 2.0 spec including mandates.
Card Adapter
Talks to acquirers (HDFC, ICICI, Axis) for card authorization. Handles 3D Secure flows, tokenization, and the RBI tokenization mandate (cards stored as tokens via the card network).
Net Banking and Wallet Adapter
Integrates with 60+ banks for net banking redirects, and with wallets like Paytm and Mobikwik. Each integration is its own protocol nightmare.
Webhook Service
Consumes state-change events. Delivers to merchant URLs with HMAC signing. Retries with exponential backoff. Tracks delivery status per attempt.
Settlement Service
Daily batch that computes merchant balances net of fees and refunds, then initiates NEFT/RTGS/IMPS transfers to merchant bank accounts. T+1 for most merchants, instant for some Prime accounts.
Reconciliation Service
Compares Razorpay's internal ledger against bank statements and NPCI settlement reports. Flags any mismatches for ops investigation. Critical for trust and compliance.
Data model
Pick the right store per table. Justify each choice with the access pattern, not by reflex.
ordersorder_id (PK)merchant_idamount_paisecurrencyorder_receipt (UNIQUE per merchant)statuscreated_atSharded by merchant_id. Order_receipt is the merchant-supplied idempotency key. State transitions are append-only via order_events.
paymentspayment_id (PK)order_idmethod (upi, card, netbanking, wallet)method_details JSONstatusamount_paisecaptured_atSharded by order_id. method_details holds rail-specific data: UPI VPA, card last 4, bank code.
refundsrefund_id (PK)payment_idamount_paiserail (original_method, instant_refund)statusinitiated_atRefunds route back to the original payment method when possible. UPI refunds are near-instant; card refunds can take 5 to 7 business days.
settlementssettlement_id (PK)merchant_idamount_paisefee_paisetax_paisenet_amount_paiseutr (bank reference)scheduled_atcompleted_atOne row per settlement batch per merchant. UTR is the bank's unique transaction reference, used for reconciliation.
ledger_entriesentry_id (PK)transaction_refaccount_idamount_paisedirection (debit, credit)posted_atAppend-only double-entry. Every payment, fee, refund, and settlement produces balanced pairs of rows.
Deep dives
These are the conversations the interviewer is steering you toward. Practice each one until you can talk through it without notes.
UPI collect requests and async callbacks
UPI works push-style: the customer's UPI app initiates the actual debit, not Razorpay. There are two flows. Intent: Razorpay generates a UPI URL (upi://pay?pa=merchant@razorpay&am=100); the customer clicks, gets redirected into their UPI app (PhonePe, GPay), confirms the transaction, and the app debits via NPCI. Collect: Razorpay calls NPCI with the customer's VPA (virtual payment address like rohan@paytm); NPCI pushes a collect request to the customer's app; the customer approves; the bank debits. In both flows, the final status comes back asynchronously via an NPCI callback (S2S webhook). Razorpay must reconcile this callback against the pending payment row. Status polling (a fallback) queries NPCI every few seconds if the callback is delayed. Both must be idempotent because a duplicate callback would otherwise double-mark the payment as paid.
Reconciliation across 60+ banks and NPCI
Every night, NPCI publishes a settlement file listing every UPI transaction that cleared during the day. Card networks (Visa, Mastercard) publish similar files via acquirers. Razorpay's Reconciliation Service pulls these files (SFTP, mostly), parses them, and compares each line to the internal ledger. Three possible outcomes: match (most common), missing on Razorpay's side (NPCI says it cleared but Razorpay does not have a record), missing on the bank's side (Razorpay thinks it cleared but the bank does not). Mismatches surface to an ops queue. The volume is high enough that a Spark job handles the diff, not a Python script. This is where you find duplicate charges, missed settlements, and revenue leakage. Without rigorous reconciliation, the ledger drifts and merchants lose trust.
RBI tokenization mandate and storing cards
Since 2022, the RBI prohibits merchants and aggregators from storing raw card numbers (PAN). Instead, every card is exchanged for a network token issued by the card network (Visa, Mastercard, Rupay). The token is bound to a specific merchant; the same card stored at two merchants gets two different tokens. For Razorpay, this means the card vault was reworked: raw PAN is captured once at first charge, exchanged for a token via the network API, and only the token is persisted. Subsequent charges use the token. This shrinks PCI scope and complies with RBI rules. The complexity is migration: existing stored cards had to be tokenized in bulk by the deadline.
Settlement T+1 and instant settlement trade-off
By default, Razorpay settles merchant balances T+1: transactions that clear today are paid out tomorrow. The settlement service runs a daily batch that aggregates per-merchant balances net of fees, GST, and refunds, then initiates NEFT or RTGS transfers. T+1 gives Razorpay 24 hours to handle chargebacks, fraud reviews, and reconciliation. For premium merchants (Prime), instant settlement is offered: as soon as a payment clears, it is paid out within hours. The trade-off is risk: Razorpay carries the float for instant settlement, and if a chargeback hits later, recovery is painful. This is priced into the higher fees on instant settlement plans.
Trade-offs to discuss
Every senior interviewer expects you to surface at least 3 of these. Pick the decisions, state the alternatives, and justify your choice.
UPI intent vs collect for merchant checkout
Intent is faster (one tap, customer is already in their UPI app) but only works on mobile. Collect works on desktop checkout (customer types VPA) but adds friction. Both must be offered.
Sync NPCI status polling vs async webhook only
Async webhook is cleaner but webhooks fail or are delayed in practice. Status polling as a fallback catches stuck payments. Both running together is standard.
Token vault in-house vs card network token
Pre-RBI mandate, in-house token vault was common. Post-mandate, network tokens are required. The in-house vault is gone; the system now persists only network tokens.
T+1 settlement vs instant
T+1 gives Razorpay 24 hours to absorb chargebacks before paying. Instant requires float and chargeback risk. Both exist as products; pricing reflects the risk.
Centralized reconciliation vs per-rail
Per-rail (separate jobs for UPI, cards, net banking) is simpler to build but causes inconsistent ops tooling. Centralized reconciliation across all rails is harder but gives a unified view of revenue. Centralized wins as the system matures.
How Razorpay actually does it
Razorpay runs on AWS in India regions, with sharded MySQL and Redis. The UPI integration with NPCI uses the NPCI APIs and a dedicated reconciliation pipeline. The card vault was rebuilt for the RBI tokenization mandate that took effect in 2022, switching from in-house tokens to network tokens issued by Visa, Mastercard, and Rupay. Settlement runs via NEFT, RTGS, and IMPS through partner banks. Razorpay's payment success rate optimization is a public engineering point: smart routing across acquirers based on real-time success rates.
Lessons to study before this interview
If any of these topics are fuzzy, the interviewer will catch it. Each lesson is 15 to 60 minutes with diagrams, code, and a quiz.