Add Payment Gateway to your Website

Add Payment Gateway to your Website

In this article, we are going to deep dive into how you can add a payment gateway like Razorpay into your website. Integration with Razorpay is relatively easy as compared to other payment methods, so let's jump right into it.

Tech Stack used in the article:

  1. React for front-end
  2. NodeJS for APIs
  3. MongoDB as Database

The first thing we'll need to do is to create a razorpay account and then go to the settings option and generate API keys for your account. Save these API keys some place safe as they won't show you again. (Note: For development purposes, click on the Test Mode in top of your screen, so we are not dealing with real money while developing and testing)

This is high level diagram that we are going to follow.

Razorpay HLD.png

The diagram seems a little complex, but trust me, the implementation is not !

So let's write some code to implement this.

Open your jsx file of the component where you want to integrate razorpay and write the initializeRazorpay function

const initializeRazorpay = () => {
        return new Promise((resolve) => {
          const script = document.createElement("script");
          script.src = "https://checkout.razorpay.com/v1/checkout.js";

          script.onload = () => {
            resolve(true);
          };
          script.onerror = () => {
            resolve(false);
          };

          document.body.appendChild(script);
        });
    }

This is the 1st point of diagram where we initialize razorpay

Then in the same file, write the makePayment function which calls you backend API. Here I am using axios to call the backend APIs.

const makePayment = async () => {
        const res = await initializeRazorpay();

        if (!res) {
          alert("Razorpay SDK Failed to load");
          return;
        }
        // Make API call to the serverless API
        axios({
            method: 'POST',
            url: `/api/subscription/`
        })
        .then(data => {
            console.log(data);
            var options = {
                key: razorpayAccountId,
                name: "Vishal Arora",
                currency: data.currency,
                amount: data.amount,
                order_id: data.id,
                description: "1 year premium subscription",
                image: "http://vishal-arora.s3-website.ap-south-1.amazonaws.com/vishal.jpg",
                handler: async function (response) {
                    // Validate payment at server - using webhooks is a better idea.
                    // Call subscription/success api
                    axios({
                        method: 'POST',
                        url: `/api/subscription/success`,
                        data: {
                            amount: data.amount,
                            razorpayPaymentId: response.razorpay_payment_id,
                            razorpayOrderId: response.razorpay_order_id,
                            razorpaySignature: response.razorpay_signature
                        }
                    }).then(res => {
                        // Add your logic here for once the payment is done
                    }).catch(err => {
                        console.log(err)
                    })
                },
                prefill: {
                    name: 'User name',
                    email: 'User email',
                    contact: 'User contact',
                },
            }

            const paymentObject = new window.Razorpay(options);
            paymentObject.open();
        })
        .catch(err => console.log(err))   
      }

In the makePayment function we first call our /api/subscription api which creates a razorpay order and sends back the orderId, which we send to razorpay along with other details like amount to window.Razorpay function. Notice how we call /api/subscription/success in the handler function. This is the function that will be called once the razorpay completes the payment.

So let's write the Code for /api/subscription and /api/subscription/success endpoints.

const shortid = require('shortid')
const Razorpay = require('razorpay')
const crypto = require('crypto')

router.post('/api/subscription/', async (req, res, next) => {
    try {
        const razorpay = new Razorpay({
            key_id: process.env.RAZORPAY_KEY_ID,
            key_secret: process.env.RAZORPAY_SECRET,
        })
        // Create an order -> generate the OrderID -> Send it to the Front-end
        const payment_capture = 1;
        const amount = 3999;
        const currency = "INR";
        const options = {
            amount: (amount * 100).toString(),
            currency,
            receipt: shortid.generate(),
            payment_capture,
        };

        const response = await razorpay.orders.create(options);
        res.status(200).json({
            id: response.id,
            currency: response.currency,
            amount: response.amount,
        });
    }  catch (error) {
        res.status(400).send(error);
    }
})

As you can see, in the /api/subscription API, we connect with razorpay with the details recieved from front end and create an instance of an order and then send those details to frontend

const shortid = require('shortid')
const Razorpay = require('razorpay')
const crypto = require('crypto')

router.post('/api/subscription/success', async (req, res, next) => {
    try {
        const {
            razorpayPaymentId,
            razorpayOrderId,
            razorpaySignature,
            amount
        } = req.body;
        const { user } = req

        // Creating our own digest
        const shasum = crypto.createHmac("sha256", process.env.RAZORPAY_SECRET);
        shasum.update(`${razorpayOrderId}|${razorpayPaymentId}`);
        const digest = shasum.digest("hex");

        // comaparing our digest with the actual signature
        if (digest !== razorpaySignature)
            return res.status(400).json({ msg: "Transaction not legit!" });

        // THE PAYMENT IS LEGIT & VERIFIED
        // Write your Business Logic here

        res.json({
            msg: "success",
            orderId: razorpayOrderId,
            paymentId: razorpayPaymentId,
            subscriptionEndDate: subscriptionEndDateResponse
        });
    }  catch (error) {
        console.log(error)
        res.status(500).send(error);
    }
})

Here in the /api/subscription/success we check the razorpay signature with signature that we created using the razorpayOrderId and razorpayPaymentId

That's it, told you the diagram was overly complex :)

Now you can call the makePayment function in your UI on a button click or however you like and you will see this screen

Razorpay.png

Go ahead and make you first payment :)

Did you find this article valuable?

Support Vishal's blog by becoming a sponsor. Any amount is appreciated!