Bird
Raised Fist0
LLDsystem_design~25 mins

Payment handling in LLD - System Design Exercise

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Design: Payment Handling System
In scope: Payment processing, status tracking, refund handling, transaction storage. Out of scope: User authentication, merchant onboarding, fraud detection.
Functional Requirements
FR1: Accept payments from users via multiple methods (credit card, debit card, digital wallets).
FR2: Process payments securely and reliably.
FR3: Support refund and cancellation requests.
FR4: Provide real-time payment status updates to users.
FR5: Maintain transaction history for audit and reporting.
FR6: Handle at least 10,000 concurrent payment requests.
FR7: Ensure payment processing latency under 2 seconds for 99th percentile.
FR8: Ensure system availability of 99.9% uptime.
Non-Functional Requirements
NFR1: Sensitive data must be encrypted and comply with PCI DSS standards.
NFR2: System must be scalable to handle peak loads during sales or events.
NFR3: Latency for payment confirmation should be low to improve user experience.
NFR4: High availability to avoid payment downtime.
NFR5: Refunds must be processed reliably and idempotently.
Think Before You Design
Questions to Ask
❓ Question 1
❓ Question 2
❓ Question 3
❓ Question 4
❓ Question 5
❓ Question 6
Key Components
API Gateway for client requests
Payment Processor service
Third-party payment gateway integrations
Database for transaction records
Cache for quick status lookups
Message queue for asynchronous processing
Notification service for status updates
Design Patterns
Event-driven architecture for asynchronous payment processing
Circuit breaker pattern for third-party gateway failures
Idempotency keys to avoid duplicate payments
Retry mechanisms for transient failures
Database transactions for consistency
Reference Architecture
Client
  |
  v
API Gateway
  |
  v
Payment Processor Service <--> Payment Gateway(s)
  |
  v
Message Queue --> Refund Processor
  |
  v
Database (Transactions)
  |
  v
Cache (Payment Status)
  |
  v
Notification Service
  |
  v
Client
Components
API Gateway
RESTful API server
Receive payment requests and route them to the payment processor
Payment Processor Service
Microservice (e.g., Node.js, Python)
Validate requests, handle business logic, interact with payment gateways
Payment Gateway(s)
Third-party services (e.g., Stripe, PayPal)
Process actual payment transactions with banks and card networks
Message Queue
RabbitMQ or Kafka
Handle asynchronous tasks like refunds and retries
Refund Processor
Microservice
Process refund requests reliably and idempotently
Database
Relational DB (e.g., PostgreSQL)
Store transaction records, payment statuses, and audit logs
Cache
Redis
Store recent payment statuses for fast retrieval
Notification Service
Push/Email service
Send real-time payment status updates to users
Request Flow
1. Client sends payment request to API Gateway.
2. API Gateway forwards request to Payment Processor Service.
3. Payment Processor validates request and generates idempotency key.
4. Payment Processor calls third-party Payment Gateway API.
5. Payment Gateway processes payment and returns result.
6. Payment Processor updates transaction status in Database.
7. Payment status cached in Redis for quick access.
8. Notification Service sends status update to client.
9. For refunds, client requests refund via API Gateway.
10. Refund Processor consumes refund request from Message Queue.
11. Refund Processor calls Payment Gateway refund API.
12. Refund status updated in Database and client notified.
Database Schema
Entities: - Transaction: id (PK), user_id, amount, currency, payment_method, status, created_at, updated_at, idempotency_key - Refund: id (PK), transaction_id (FK), amount, status, created_at, updated_at - PaymentMethod: id (PK), type (card, wallet), details (encrypted), user_id Relationships: - One Transaction belongs to one User - One Refund belongs to one Transaction - One User can have multiple PaymentMethods
Scaling Discussion
Bottlenecks
Payment Processor service CPU and memory under high concurrent load.
Database write and read throughput for transaction records.
Third-party payment gateway rate limits and latency.
Message queue backlog during peak refund requests.
Cache invalidation and consistency under heavy updates.
Solutions
Scale Payment Processor horizontally with load balancer and stateless design.
Use database sharding or read replicas to distribute load.
Implement circuit breakers and fallback strategies for payment gateways.
Increase message queue partitions and consumers for parallel refund processing.
Use cache expiration policies and event-driven cache updates to maintain consistency.
Interview Tips
Time: Spend 10 minutes understanding requirements and clarifying scope, 20 minutes designing architecture and data flow, 10 minutes discussing scaling and trade-offs, 5 minutes summarizing.
Emphasize security and compliance with PCI DSS.
Explain asynchronous processing for refunds and retries.
Discuss idempotency to avoid duplicate payments.
Highlight how caching improves user experience with fast status updates.
Describe how to handle third-party failures gracefully.
Show understanding of scaling bottlenecks and mitigation strategies.

Practice

(1/5)
1. What is the primary purpose of a payment handling system in software design?
easy
A. To store user profile pictures
B. To securely process and record financial transactions
C. To manage user login and authentication
D. To display product information to users

Solution

  1. Step 1: Understand the role of payment handling

    Payment handling systems focus on managing money transfers safely and reliably.
  2. Step 2: Identify the core function

    The core function is to process payments securely and keep records of transactions.
  3. Final Answer:

    To securely process and record financial transactions -> Option B
  4. Quick Check:

    Payment handling = Secure transaction processing [OK]
Hint: Payment handling means safe money transfer and record keeping [OK]
Common Mistakes:
  • Confusing payment handling with user authentication
  • Thinking it manages product display
  • Assuming it stores user media files
2. Which of the following is the correct sequence of steps in a typical payment processing flow?
easy
A. Notify user -> Record transaction -> Process payment -> Validate payment details
B. Record transaction -> Validate payment details -> Notify user -> Process payment
C. Validate payment details -> Process payment -> Record transaction -> Notify user
D. Process payment -> Notify user -> Validate payment details -> Record transaction

Solution

  1. Step 1: Identify logical payment flow order

    First, payment details must be validated to ensure correctness.
  2. Step 2: Follow with processing, recording, and notifying

    After validation, payment is processed, transaction recorded, then user notified.
  3. Final Answer:

    Validate payment details -> Process payment -> Record transaction -> Notify user -> Option C
  4. Quick Check:

    Payment flow = Validate -> Process -> Record -> Notify [OK]
Hint: Payment flows from validation to processing, then record and notify [OK]
Common Mistakes:
  • Not validating before processing
  • Not recording transaction before notifying
  • Mixing notification before processing
3. Consider this simplified payment processing pseudocode:
def process_payment(amount, card_info):
    if not validate_card(card_info):
        return "Invalid card"
    if amount <= 0:
        return "Invalid amount"
    if not charge_card(card_info, amount):
        return "Charge failed"
    record_transaction(card_info, amount)
    return "Payment successful"

What will be the output of process_payment(100, 'expired_card') if validate_card returns False for expired cards?
medium
A. "Invalid card"
B. "Charge failed"
C. "Payment successful"
D. "Invalid amount"

Solution

  1. Step 1: Check card validation result

    Since validate_card returns False for expired cards, the first if condition triggers.
  2. Step 2: Return error message immediately

    The function returns "Invalid card" without further processing.
  3. Final Answer:

    "Invalid card" -> Option A
  4. Quick Check:

    Expired card -> validate_card = False -> "Invalid card" [OK]
Hint: If validation fails, function returns error immediately [OK]
Common Mistakes:
  • Assuming charge_card runs despite invalid card
  • Confusing invalid amount with invalid card
  • Expecting success despite validation failure
4. A payment system logs duplicate transactions when retrying failed payments. Which design fix will best prevent this issue?
medium
A. Use unique transaction IDs and check before recording
B. Increase payment timeout duration
C. Remove transaction logging entirely
D. Allow multiple retries without checks

Solution

  1. Step 1: Identify cause of duplicate logs

    Retries cause repeated transaction records without uniqueness checks.
  2. Step 2: Implement unique transaction IDs and check

    Assign unique IDs and verify before logging to avoid duplicates.
  3. Final Answer:

    Use unique transaction IDs and check before recording -> Option A
  4. Quick Check:

    Unique IDs prevent duplicate transaction logs [OK]
Hint: Unique IDs stop duplicate transaction records [OK]
Common Mistakes:
  • Ignoring duplicate checks on retries
  • Removing logging which loses audit trail
  • Increasing timeout doesn't fix duplicates
5. You are designing a payment system that must handle 10,000 transactions per second with minimal latency and high reliability. Which architectural approach best supports this requirement?
hard
A. Store all payment requests in a single database table and process sequentially
B. Process all payments synchronously on a single server to ensure order
C. Use client-side scripts to process payments directly without server validation
D. Use a distributed message queue to process payments asynchronously with multiple worker nodes

Solution

  1. Step 1: Analyze scalability and latency needs

    Handling 10,000 TPS requires distributing load and minimizing blocking.
  2. Step 2: Choose asynchronous distributed processing

    Using a message queue with multiple workers allows parallel processing and reliability.
  3. Step 3: Eliminate options causing bottlenecks or insecurity

    Single server or sequential DB processing causes bottlenecks; client-side processing lacks security.
  4. Final Answer:

    Use a distributed message queue to process payments asynchronously with multiple worker nodes -> Option D
  5. Quick Check:

    High TPS + low latency = distributed async processing [OK]
Hint: Distribute load with async workers for high TPS [OK]
Common Mistakes:
  • Using single server causing bottlenecks
  • Sequential DB processing slowing throughput
  • Relying on client-side payment processing