DEV Community

Cover image for Implementing Factory Design Pattern for Multiple Payment Integrations
Srashti Gupta
Srashti Gupta

Posted on

Implementing Factory Design Pattern for Multiple Payment Integrations

Introduction

When integrating multiple payment methods (Online, POS, and Payment Links), maintaining a flexible and scalable architecture is crucial. The Factory Design Pattern allows us to dynamically create payment processors based on the given type. In this blog, we’ll explore how to implement it efficiently.

Understanding Payment Methods

Before diving into the code, let's quickly define the three main payment types:

  • Payment Gateway (PG): Handles online payments directly through services like Razorpay, Paytm, or CashFree.
  • Point of Sale (POS): In-store payment processing through card machines.
  • Payment Links: Allows merchants to send payment links for remote transactions. ## Step 1: Define Payment Processors ### Online Payment Processors
class RazorpayPG {
  process() { console.log("Processing Razorpay PG Payment"); }
}

class PaytmPG {
  process() { console.log("Processing Paytm PG Payment"); }
}

class CashFreePG {
  process() { console.log("Processing CashFree PG Payment"); }
}
Enter fullscreen mode Exit fullscreen mode

POS Payment Processors

class PaytmPOS {
  process() { console.log("Processing Paytm POS Payment"); }
}

class RazorpayPOS {
  process() { console.log("Processing Razorpay POS Payment"); }
}

class CashFreePOS {
  process() { console.log("Processing CashFree POS Payment"); }
}
Enter fullscreen mode Exit fullscreen mode

Payment Link Processors

class RazorpayLink {
  generate() { console.log("Generating Razorpay Payment Link"); }
}

class PaytmLink {
  generate() { console.log("Generating Paytm Payment Link"); }
}

class CashFreeLink {
  generate() { console.log("Generating CashFree Payment Link"); }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Implement the Factory Class

Now, let’s create a Factory Class that will dynamically generate the required payment processor.

class PaymentFactory {
  static createPayment(type, provider) {
    // Mapping payment types to their respective classes
    const paymentTypes = {
      online: { razorpay: RazorpayPG, paytm: PaytmPG, cashfree: CashFreePG },
      pos: { razorpay: RazorpayPOS, paytm: PaytmPOS, cashfree: CashFreePOS },
      paymentLink: { razorpay: RazorpayLink, paytm: PaytmLink, cashfree: CashFreeLink },
    };

    // Validate type and provider
    if (!paymentTypes[type] || !paymentTypes[type][provider]) {
      throw new Error("Invalid payment type or provider");
    }

    return new paymentTypes[type][provider]();
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Using the Factory Pattern

Now, we can dynamically create payment instances based on the payment type.

// Example 1: Processing an Online Payment with Razorpay
const payment1 = PaymentFactory.createPayment("online", "razorpay");
payment1.process();  // Output: Processing Razorpay PG Payment

// Example 2: Processing a POS Payment with Paytm
const payment2 = PaymentFactory.createPayment("pos", "paytm");
payment2.process();  // Output: Processing Paytm POS Payment

// Example 3: Generating a Payment Link via CashFree
const payment3 = PaymentFactory.createPayment("paymentLink", "cashfree");
payment3.generate();  // Output: Generating CashFree Payment Link
Enter fullscreen mode Exit fullscreen mode

How the Factory Pattern Works

Step-by-Step Flow:
1️⃣ User requests a payment method (online, pos, or paymentLink).
2️⃣ The Factory Class selects the correct provider (razorpay, paytm, cashfree).
3️⃣ The corresponding class instance is created dynamically.
4️⃣ The process() or generate() function is executed based on the type.

Advantages of Using the Factory Pattern

Scalability: Easily add new payment methods without modifying existing code.
Maintainability: Reduces duplicate code and centralizes payment processing logic.
Flexibility: Dynamically selects the correct payment class based on input parameters.

Final Thoughts

Using the Factory Design Pattern simplifies managing multiple payment integrations in your application. With this approach, you can easily scale and modify the system without breaking existing functionality.

Let me know in the comments if you have any questions or suggestions! 🚀

Top comments (0)