loading...
Cover image for Dependency Inversion With Payment Gateways Stripe/Paypal Using Nodejs

Dependency Inversion With Payment Gateways Stripe/Paypal Using Nodejs

eslamelkholy profile image eslamelkholy ・2 min read

What We Are Going To Cover Today

  • Idea Of Dependency Inversion
  • Problem/Solution With Payment Gateways Stripe/Paypal
  • Real Scenario You Can use in your E-commerce Project

Dependency inversion

  • High level Modules should not depend on low level modules Both Should Depend on Abstraction
  • Or We Can Say Any higher classes should always depend upon the abstraction of the class rather than the detail.

From This Definition We Can Say That

We Just want Our Code Depends On The Wrapper We Created Not The Actual Implementation Of Dependency We're Using

The Problem We Have

  • Change Payment Gateway From Stripe >> Paypal Will Be Very Hard and We Will Change tons Of Code
  • Our Code Depends on the Actual Implementation Of The Payment Service and This Going to be Hard to Maintain
  • Testing Everything From Scratch Again
  • Making any Transaction Going To Be Really Hard to Trace Later

Solution

Dependency Inversion With Stripe/Paypal

  • Create Intermediate Layer This Layer Going to Be Wrapper Around Payment Gateway Services
  • e.g StripeServiceWrapper, PaypalServiceWrapper
  • So We Just Abstract the Payment Gateways Idea Using These Wrappers it's
  • Our Code Now Depends On These Wrappers Not The Actual Implementation Of Dependency We're Using

Let's Start By Some Code Snippets

Payment Store
Here We Are Going to Inject The Wrapper And Makes The Transaction With Anyone We Want Easily

import PaymentService from "./PaymentService";
class PaymentStore {
  constructor(paymentWrapper) {
    this.paymentWrapper = paymentWrapper;
    this.paymentService = new PaymentService();
  }

  async makeTransaction(chargeData) {
    const charge = await this.paymentWrapper.createCharge(chargeData);
    await this.paymentService.addNewCharge(charge);
    return charge;
  }
}

export default PaymentStore;
Enter fullscreen mode Exit fullscreen mode

Stripe Wrapper

import Stripe from "stripe";
import mockPayment from "./Stripe/mockPayment";
class StripeServiceWrapper {
  constructor() {
    this.stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
  }
  async createCharge() {
    const { amount, currency, description, source } = mockPayment;
    const charge = await this.stripe.charges.create({
      amount,
      currency,
      description,
      source,
    });
    return charge;
  }

  async createCustomer(customerData) {
    const { name, email, source, address, phone } = customerData;
    const customer = await stripe.customers.create({
      address,
      name,
      email,
      phone,
      source,
    });
    return customer;
  }
}

export default StripeServiceWrapper;
Enter fullscreen mode Exit fullscreen mode

Paypal Wrapper

import paypal from "paypal-rest-sdk";
import "./PayPal/PayPalConfig";

class PayPalServiceWrapper {
  createCharge({ payment_object, paymentId }) {
    return new Promise(function (resolve, reject) {
      paypal.payment.execute(paymentId, payment_object, function (error, payment) {
        if (error) reject(error);
        else {
          const { id, transactions } = payment;
          resolve({ id, amount: parseInt(transactions[0].amount.total) });
        }
      });
    });
  }

  paymentExecutionLink(paymentObject) {
    return new Promise(function (resolve, reject) {
      paypal.payment.create(paymentObject, function (error, payment) {
        if (error) reject(error);
        else resolve(payment);
      });
    });
  }

  getRedirectLink(links) {
    for (let i = 0; i < links.length; i++) {
      if (links[i].rel === "approval_url") return links[i].href;
    }
  }
}

export default PayPalServiceWrapper;
Enter fullscreen mode Exit fullscreen mode
So Now At Our Controller It's Going to Be Very Easy To Switch From Stripe To Paypal
const post = async (req, res) => {
  const store = new PaymentStore(new StripeServiceWrapper());
  await store.makeTransaction();
  return res.status(200).send({SUCCESS_MESSAGE});
};
Enter fullscreen mode Exit fullscreen mode

You Can Find The Code And How to Start Easy At

https://github.com/eslamelkholy/Payment-Gateway-Stripe-Paypal-Using-Dependency-Inversion

References

https://en.wikipedia.org/wiki/Dependency_inversion_principle

https://www.geeksforgeeks.org/dependecy-inversion-principle-solid/

https://www.youtube.com/watch?v=9oHY5TllWaU&list=PLZlA0Gpn_vH_CthENcPCM0Dww6a5XYC7f&index=11&ab_channel=WebDevSimplified

https://dev.to/educative/s-o-l-i-d-principles-of-object-oriented-programming-in-c-2m98#dependency

Discussion

pic
Editor guide