System Design ( Day - 59 )
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
Client calls
PaymentController.handlePayment(...).The Factory returns the selected
PaymentGateway.PaymentService(singleton) configures that gateway.Service invokes the gateway’s validation, initiation, and confirmation steps.
Each gateway talks to its own
BankingSystemimplementation under the covers.
🌟 Why This Design?
Open/Closed: Add new gateways by creating a new
PaymentGateway+BankingSystem, then register inGatewayFactory.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
PaymentGatewayinterface, never concrete classes.Global Access: Key managers/services are singletons, ensuring consistent state and easy access across your app.