Skip to main content

Command Palette

Search for a command to run...

System Design ( Day - 59 )

Published
2 min read

Payment Gateway system

Requirements
1. Should support multiple providers ( Paytm, razorpay etc.. )
2. we can easily add new gateways in future
3. There should be standard payment flow with required validators.
4. Have error handling and retires mechanism

Flow
We’ll receive the Payment request from the client and we’ll validate it and send it to the gateway this gateway is nothing but a way to connect to the providers like Paytm or razorpay etc, through this we’ll interact with providers banking system, after getting the confirmation from the providers we’ll send the response to the client.

🏗️ Core Components

1. PaymentRequest

A simple data class holding:

textCopyEditsender, receiver, amount, currency

2. PaymentGateway (Interface + Strategy)

Defines the steps every gateway must implement:

textCopyEditprocessPayment(req)
validatePayment(req)
initiatePayment(req)
confirmPayment(req)

Concrete strategies: PaytmGateway, RazorpayGateway, etc.

3. GatewayFactory (Singleton + Factory)

textCopyEditGatewayFactory.getInstance().getGateway(GatewayType)

Returns the correct PaymentGateway based on an enum (PAYTM, RAZORPAY, …).

4. BankingSystem (Abstract + Implementations)

Hides each gateway’s underlying bank API:

textCopyEditprocessPayment(amount)

Concrete: PaytmBankingSystem, RazorpayBankingSystem.

5. PaymentService (Singleton + Facade)

Coordinates the operation:

textCopyEditsetGateway(gateway)
processPayment(req) {
  gateway.validatePayment(req);
  gateway.initiatePayment(req);
  return gateway.confirmPayment(req);
}

6. PaymentController (Entry Point, Singleton)

Exposes a clean method to your web or mobile layer:

textCopyEdithandlePayment(GatewayType gt, PaymentRequest req) {
  PaymentGateway pg = GatewayFactory.getInstance().getGateway(gt);
  service.setGateway(pg);
  return service.processPayment(req);
}

📈 How It Flows

  1. Client calls PaymentController.handlePayment(...).

  2. The Factory returns the selected PaymentGateway.

  3. PaymentService (singleton) configures that gateway.

  4. Service invokes the gateway’s validation, initiation, and confirmation steps.

  5. Each gateway talks to its own BankingSystem implementation under the covers.


🌟 Why This Design?

  • Open/Closed: Add new gateways by creating a new PaymentGateway + BankingSystem, then register in GatewayFactory.

  • Single Responsibility: Controllers handle HTTP, services orchestrate flow, gateways implement each provider’s logic, factories do lookups.

  • Loose Coupling: The controller and service know only about the PaymentGateway interface, never concrete classes.

  • Global Access: Key managers/services are singletons, ensuring consistent state and easy access across your app.

System Design

Part 1 of 50