Payment Processing System Design (HLD & LLD)
Problem Statement
Section titled “Problem Statement”Design a payment processing system similar to Stripe, Razorpay, or PayPal that:
- Accepts payments from users
- Supports multiple payment methods
- Communicates with external payment gateways
- Ensures idempotency
- Handles failures and retries
- Maintains transaction history
- Supports refunds
- Provides high reliability and consistency
Functional Requirements
Section titled “Functional Requirements”- User initiates a payment.
- Support multiple payment methods:
- Credit Card
- Debit Card
- UPI
- Wallet
- Net Banking
- Process payments through external payment gateways.
- Persist transaction details.
- Handle payment success, failure, and pending states.
- Support refunds.
- Provide APIs for transaction status.
Non-Functional Requirements
Section titled “Non-Functional Requirements”- High availability
- Strong consistency for financial transactions
- Idempotent APIs
- PCI-compliant security
- Horizontal scalability
- Low latency
High-Level Design (HLD)
Section titled “High-Level Design (HLD)”Architecture
Section titled “Architecture”flowchart TD
C[Client]
A[API Gateway]
P[Payment Service]
PR[Payment Processor]
F[Fraud Detection]
G[Gateway Adapter]
X[External Payment Gateway]
B[Bank / Card Network]
C --> A --> P
P --> PR
P --> F
PR --> G --> X --> B
Additional supporting components:
- Transaction Database
- Redis Cache
- Kafka / Message Queue
- Notification Service
- Ledger Service
Payment Flow
Section titled “Payment Flow”sequenceDiagram
participant User
participant API as API Gateway
participant PS as Payment Service
participant PP as Payment Processor
participant PG as Payment Gateway
participant Bank
User->>API: Create Payment
API->>PS: Validate & Create Order
PS->>PP: Process Payment
PP->>PG: Gateway Request
PG->>Bank: Authorize
Bank-->>PG: Result
PG-->>PS: Callback/Webhook
PS-->>User: Payment Status
Microservices
Section titled “Microservices”Payment Service
Section titled “Payment Service”Responsibilities:
- Create payment
- Validate request
- Query payment status
APIs:
POST /paymentsGET /payments/{id}POST /payments/{id}/refundPayment Processor
Section titled “Payment Processor”Responsible for:
- Selecting payment gateway
- Retrying failed requests
- Idempotency handling
Gateway Adapter
Section titled “Gateway Adapter”Implements the Strategy Pattern.
Examples:
- StripeAdapter
- RazorpayAdapter
- PaypalAdapter
Ledger Service
Section titled “Ledger Service”Maintains double-entry bookkeeping.
| Account | Entry |
|---|---|
| User | Debit |
| Merchant | Credit |
Notification Service
Section titled “Notification Service”Sends:
- Payment success
- Payment failure
- Refund confirmation
Channels:
- SMS
- Push Notification
Database Design
Section titled “Database Design”Payments
Section titled “Payments”payments---------id (UUID)user_idamountcurrencystatuspayment_methodgatewaycreated_atupdated_atTransactions
Section titled “Transactions”transactions-------------idpayment_idgateway_transaction_idstatusresponse_codecreated_atRefunds
Section titled “Refunds”refunds--------idpayment_idamountstatuscreated_atIdempotency
Section titled “Idempotency”To prevent duplicate payments when users retry requests:
Use an Idempotency-Key header.
Idempotency-Key: UUIDStore:
idempotency_keyrequest_hashresponseDuplicate requests return the previously stored response.
Failure Handling
Section titled “Failure Handling”Possible failures:
- Gateway timeout
- Network issues
- Bank decline
- Internal service failure
Solutions:
- Retry with exponential backoff.
- Use Kafka/RabbitMQ for asynchronous processing.
- Apply Circuit Breaker (e.g., Resilience4j).
Payment Lifecycle
Section titled “Payment Lifecycle”stateDiagram-v2
[*] --> CREATED
CREATED --> PROCESSING
PROCESSING --> SUCCESS
PROCESSING --> FAILED
SUCCESS --> REFUNDED
States:
- CREATED
- PROCESSING
- SUCCESS
- FAILED
- PENDING
- REFUNDED
Security
Section titled “Security”- PCI-DSS compliance
- Tokenization of card data
- Encryption
- HTTPS
- HMAC signature verification for webhooks
Webhook verification flow:
Gateway -> Webhook -> Verify SignatureScaling Strategy
Section titled “Scaling Strategy”Horizontal Scaling
Section titled “Horizontal Scaling”Payment Service -> Multiple InstancesBehind a load balancer.
Database Scaling
Section titled “Database Scaling”- Read replicas
- Sharding by merchant_id
Event-Driven Processing
Section titled “Event-Driven Processing”Events:
PAYMENT_CREATEDPAYMENT_COMPLETEDPAYMENT_FAILEDREFUND_INITIATEDLow-Level Design (LLD)
Section titled “Low-Level Design (LLD)”Payment Entity
Section titled “Payment Entity”class Payment {
private String id; private String userId; private double amount; private PaymentStatus status; private PaymentMethod method; private String gateway;}PaymentStatus
Section titled “PaymentStatus”public enum PaymentStatus { CREATED, PROCESSING, SUCCESS, FAILED, REFUNDED}PaymentMethod
Section titled “PaymentMethod”public enum PaymentMethod { CARD, UPI, NETBANKING, WALLET}PaymentGateway Interface
Section titled “PaymentGateway Interface”public interface PaymentGateway {
PaymentResponse processPayment(PaymentRequest request);
}StripeGateway
Section titled “StripeGateway”public class StripeGateway implements PaymentGateway {
public PaymentResponse processPayment(PaymentRequest request) { // call stripe API return response; }
}RazorpayGateway
Section titled “RazorpayGateway”public class RazorpayGateway implements PaymentGateway {
public PaymentResponse processPayment(PaymentRequest request) { // call razorpay API return response; }
}PaymentGatewayFactory
Section titled “PaymentGatewayFactory”public class PaymentGatewayFactory {
public static PaymentGateway getGateway(String gateway) {
switch(gateway) { case "STRIPE": return new StripeGateway(); case "RAZORPAY": return new RazorpayGateway(); default: throw new IllegalArgumentException(); } }
}PaymentService
Section titled “PaymentService”@Servicepublic class PaymentService {
public PaymentResponse processPayment(PaymentRequest request) {
PaymentGateway gateway = PaymentGatewayFactory.getGateway(request.getGateway());
return gateway.processPayment(request); }
}Design Patterns
Section titled “Design Patterns”| Pattern | Usage |
|---|---|
| Strategy | Gateway adapters |
| Factory | Gateway selection |
| State | Payment lifecycle |
| Observer | Notifications |
| Circuit Breaker | Gateway resilience |
Advanced Topics
Section titled “Advanced Topics”- Distributed locking (Redis) to prevent duplicate processing.
- Outbox Pattern for reliable DB + event publishing.
- Saga Pattern for refund orchestration.
- Rate limiting for fraud prevention.
Common Interview Follow-up Questions
Section titled “Common Interview Follow-up Questions”- How do you ensure exactly-once payment processing?
- How do you design a financial ledger?
- How do you reconcile payment mismatches?
- How do you recover from partial failures?
Key Takeaways
Section titled “Key Takeaways”- Separate orchestration, gateway integration, ledger, and notification concerns.
- Idempotency is critical to avoid duplicate charges.
- Event-driven architecture improves scalability and resilience.
- Strategy and Factory patterns simplify multi-gateway support.
- Strong consistency, security, and auditability are essential for payment systems.