Razorpay Integration with NodeJS

Dani Ram SahuDani Ram Sahu
13 min read

Introduction:

Online payments are an essential part of any e-commerce or online business. They allow customers to pay for goods or services using their preferred payment method and currency. However, integrating online payments can be a challenging task for developers, as they have to deal with various aspects such as security, compliance, user experience, etc. That's where Razorpay comes in handy.

Razorpay is a payment gateway that provides a simple and secure way to accept online payments from customers. It supports multiple payment modes such as credit cards, debit cards, net banking, UPI, wallets, etc. It also supports multiple currencies and international payments. Razorpay handles all the complexities and risks involved in online payments and provides a seamless and hassle-free experience for both developers and customers.

In this tutorial, we will learn how to integrate Razorpay with our NodeJS-based website using their SDK. Nodejs is a popular and powerful technology that allows us to create web servers and applications using JavaScript. Nodejs is fast, scalable, and easy to use. However, it also has some drawbacks such as callback hell, error handling, etc.

To follow along with this tutorial, you will need some basic knowledge of NodeJS, Express, HTML, and JavaScript. You will also need a Razorpay account and API keys in test mode. If you don't have them already, you can create them from the Razorpay dashboard. You can also refer to the official documentation of Razorpay or some of the tutorials available online for more details.

Setting up the Razorpay account and API keys:

Before we start integrating Razorpay with our NodeJS website, we need to create a Razorpay account and generate the API keys in test mode. These are required to access the Razorpay APIs and perform various operations such as creating orders, capturing payments, verifying signatures, etc.

  • To create a Razorpay account, you can go to https://dashboard.razorpay.com/signup and enter your email address and other necessary information. You can also select your business type and category from the options available. Once you sign up, you can log in to the dashboard where you can manage your payments, orders, customers, etc.

  • To generate the API keys, you can go to the settings section in the dashboard and click on the API keys tab. You can then click on the generate button and copy the key id and key secret that are displayed. You can also download the keys as a file for backup purposes. You should keep these keys safe and secure as they are used to access the Razorpay APIs.

  • The API keys are used to authenticate requests to the Razorpay APIs. They are passed as headers in every request along with other parameters. The key id is used to identify your account and the key secret is used to verify your request. The Razorpay APIs use basic authentication to validate your credentials and grant access to your account.

Setting up the NodeJS project and installing the modules:

Now that we have created our Razorpay account and generated our API keys, we can start setting up our NodeJSproject and installing the modules we need for this tutorial. We will use Express as our web framework and Razorpay as our module to interact with the Razorpay APIs.

To create a NodeJS project, we can use the npm init command in our terminal and answer some questions about our project. This will create a package.json file that contains some information and configurations about our project. We can also create an app.js file that will contain our server code.

To install the express and Razorpay modules, we can use the npm install command in our terminal and specify the names of the modules. This will download and save the modules in our node_modules folder and also update our package.json file with the dependencies. We can also use the --save flag to save the modules as dependencies in our package.json file.

$ npm init
name: (razorpay-nodejs) 
version: (1.0.0) 
description: A tutorial on Razorpay integration with nodejs
entry point: (index.js) app.js
test command: 
git repository: 
keywords: razorpay, nodejs, express
author: 
license: (ISC)
 npm install express razorpay --save

This is how packet.json file will look

 "name": "razorpay-nodejs",
  "version": "1.0.0",
  "description": "A tutorial on Razorpay integration with nodejs",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "razorpay",
    "nodejs",
     "express"
  ],
   "author": "",
  "license": "ISC"
}

Express is a web framework for NodeJS that allows us to create and run web servers and applications using JavaScript. Express provides various features and functionalities such as routing, middleware, templating, etc. that make it easy and convenient to develop web in NodeJS.

Razorpay is a module for NodeJS that allows us to interact with the Razorpay APIs using JavaScript. Razorpay provides various methods and functions that help us perform various operations such as creating orders, capturing payments, verifying signatures, etc. using the Razorpay APIs.

Creating the express server and handling requests:

In this section, we will create an express server and handle requests from our front-end. We will also use the Razorpay module to interact with the Razorpay APIs and perform various operations such as creating orders, capturing payments, verifying signatures, etc.

To create an express server, we need to require the express module and create an app object that represents our web application. We also need to use the app.listen method to start the server and listen for incoming requests on a specified port. We also need to use the app.use method to apply some middleware functions that can process the requests before they reach our routes. For example, we need to use express.json middleware to parse the request body as JSON.

// Require express module
import express from "express";

// Create app object
const app = express();

// Use express.json middleware
app.use(express.json());

// Start server on port 3000
app.listen(3000, () => {
  console.log("Server is running on port 3000");
});

To handle requests from our front-end, we need to use the app.get and app.post methods to define some routes that can handle GET and POST requests respectively. We also need to use the req and res parameters to access the request and response objects respectively. For example, we need to use the req.body to access the data sent by the frontend and use the res.json or res.send methods to send data back to the frontend.

// Handle GET request on / route
app.get("/", (req, res) => {
  // Send a welcome message
  res.send("Welcome to Razorpay integration with nodejs");
});

// Handle POST request on /order route
app.post("/order", (req, res) => {
  // Get order details from request body
  const { amount, currency } = req.body;

  // TODO: Create order using razorpay module

  // TODO: Send order id back to frontend
});

To use the Razorpay module, we need to import it in our app.js file and create a razorpay instance using our API keys. We can then use the razorpay instance to access various methods and functions that help us interact with the Razorpay APIs. For example, we need to use the razorpay.orders.create method to create an order with some details such as amount, currency, receipt, etc. and get an order id in return. We also need to use the razorpay.payments.capture method to capture a payment with some details such as payment id, amount, currency, etc. and get a payment object in return. We also need to use the razorpay.utils.validateWebhookSignature method to verify a signature from the Razorpay server with some details such as payload, signature, secret, etc. and get a boolean value in return.


// Import razorpay module
import Razorpay from "razorpay";

// Create razorpay instance using API keys
const razorpay = new Razorpay({
  key_id: "YOUR_KEY_ID",
  key_secret: "YOUR_KEY_SECRET",
});

// Create order using razorpay.orders.create method
razorpay.orders.create(
  {
    amount: amount,
    currency: currency,
    receipt: "receipt#1",
    payment_capture: 1,
  },
  (err, order) => {
    if (err) {
      // Handle error
      console.log(err);
      res.status(400).send(err);
    } else {
      // Get order id from order object
      const orderId = order.id;

      // Send order id back to frontend
      res.json({ orderId: orderId });
    }
  }
);

// Capture payment using razorpay.payments.capture method
razorpay.payments.capture(paymentId, amount, currency).then((payment) => {
  // Get payment status from payment object
  const paymentStatus = payment.status;

  // Send payment status back to frontend
  res.json({ paymentStatus: paymentStatus });
});

// Verify signature using razorpay.utils.validateWebhookSignature method
const isValidSignature = razorpay.utils.validateWebhookSignature(
  payload,
  signature,
  secret
);

// Check if signature is valid or not
if (isValidSignature) {
  // Signature is valid
} else {
  // Signature is invalid
}

To send responses back to our frontend, we need to use the res.json or res.send methods to send data in JSON or plain text format respectively. We also need to use the res.status method to set the status code of the response. For example, we need to send a 200 status code for a successful response or a 400 status code for a bad request.

// Send data in JSON format using res.json method
res.json({ data: data });

// Send data in plain text format using res.send method
res.send("Data");

// Set status code of response using res.status method
res.status(200); // OK
res.status(400); // Bad Request

Creating the Frontend and displaying the Payment Button and Form:

In this section, we will create a frontend using HTML and JavaScript that can display a payment button and a Razorpay checkout form when the user clicks on it. We will also use the Razorpay checkout script to customize the payment form and handle the payment events. We will also use fetch or axios to send requests to our express server and receive responses.

To create a frontend using HTML and JavaScript, we need to create an index.html file that will contain our HTML code and a script.js file that will contain our JavaScript code. We also need to link the script.js file in our index.html file using the script tag. We also need to link the Razorpay checkout script in our index.html file using the script tag and the src attribute.

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Razorpay integration with nodejs</title>
  </head>
  <body>
    <!-- Create a button that can trigger a function when clicked -->
    <button onclick="pay()">Pay Rs. 499</button>

    <!-- Link script.js file -->
    <script src="script.js"></script>

    <!-- Link Razorpay checkout script -->
    <script src="https://checkout.razorpay.com/v1/checkout.js"></script>
  </body>
</html>

To display a payment button and a Razorpay checkout form, we need to use the button tag and the onclick attribute in our HTML code to create a button that can trigger a function when clicked. We also need to use the Razorpay function and the open method in our JavaScript code to create and open a Razorpay checkout form with some options such as key, amount, currency, order_id, etc. We also need to use the callback_url option to specify a URL where the Razorpay server will send a POST request with the payment details after the payment is completed.

// Define a function that can trigger when button is clicked
function pay() {
  // Create an order using fetch or axios
  fetch("/order", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      amount: 49900,
      currency: "INR",
    }),
  })
    .then((res) => res.json())
    .then((data) => {
      // Get order id from data
      const orderId = data.orderId;

      // Create an options object for Razorpay checkout form
      const options = {
        key: "YOUR_KEY_ID", // Replace with your key id
        amount: 49900,
        currency: "INR",
        name: "Razorpay integration with nodejs",
        description: "A tutorial on Razorpay integration with nodejs",
        image: "https://example.com/logo.png", // Replace with your logo url
        order_id: orderId,
        handler: function (response) {
          // Get payment id from response
          const paymentId = response.razorpay_payment_id;

          // Capture payment using fetch or axios
          fetch("/capture", {
            method: "POST",
            headers: {
              "Content-Type": "application/json",
            },
            body: JSON.stringify({
              paymentId: paymentId,
              amount: 49900,
              currency: "INR",
            }),
          })
            .then((res) => res.json())
            .then((data) => {
              // Get payment status from data
              const paymentStatus = data.paymentStatus;

              // Display payment status
              alert(`Payment status: ${paymentStatus}`);
            })
            .catch((err) => {
              // Handle error
              console.log(err);
              alert("Payment failed");
            });
        },
        prefill: {
          name: "John Doe",
          email: "johndoe@example.com",
          contact: "+919876543210",
        },
        notes: {
          address: "Some address",
        },
        theme: {
          color: "#F37254",
        },
        callback_url:
          "https://example.com/callback", // Replace with your callback url
      };

      // Create a Razorpay instance using options object
      const rzp = new Razorpay(options);

      // Open Razorpay checkout form
      rzp.open();
    })
    .catch((err) => {
      // Handle error
      console.log(err);
      alert("Order creation failed");
    });
}

To customize the payment form and handle the payment events, we need to use the theme, notes, prefill, modal, etc. options in our JavaScript code to change the appearance and behavior of the Razorpay checkout form. We also need to use the onPaymentFailed and onPaymentSuccess methods to define some functions that can handle the payment failure and success events respectively. We also need to use the response parameter to access the payment id, order id, signature, etc. from the Razorpay server.

// Create an options object for Razorpay checkout form
const options = {
  key: "YOUR_KEY_ID", // Replace with your key id
  amount: 49900,
  currency: "INR",
  name: "Razorpay integration with nodejs",
  description: "A tutorial on Razorpay integration with nodejs",
  image: "https://example.com/logo.png", // Replace with your logo url
  order_id: orderId,
  handler: function (response) {
    // Get payment id from response
    const paymentId = response.razorpay_payment_id;

    // Capture payment using fetch or axios
    fetch("/capture", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({
        paymentId: paymentId,
        amount: 49900,
        currency: "INR",
      }),
    })
      .then((res) => res.json())
      .then((data) => {
        // Get payment status from data
        const paymentStatus = data.paymentStatus;

        // Display payment status
        alert(`Payment status: ${paymentStatus}`);
      })
      .catch((err) => {
        // Handle error
        console.log(err);
        alert("Payment failed");
      });
  },
  prefill: {
    name: "John Doe",
    email: "johndoe@example.com",
    contact: "+919876543210",
  },
  notes: {
    address: "Some address",
  },
  theme: {
    color: "#F37254",
  },
  callback_url:
    "https://example.com/callback", // Replace with your callback url

  // Define some functions for onPaymentFailed and onPaymentSuccess events
  onPaymentFailed(response) {
    console.log(response.error.code);
    console.log(response.error.description);
    console.log(response.error.source);
    console.log(response.error.step);
    console.log(response.error.reason);
    console.log(response.error.metadata.order_id);
    console.log(response.error.metadata.payment_id);
  },

  onPaymentSuccess(response) {
    console.log(response.order_id);
    console.log(response.payment_id);
    console.log(response.signature);
  },

  modal:{
     escape:true,
     backdropclose:true,
      ondismiss: function(){
       // Handle modal dismissal
       console.log("Modal dismissed");
     }
   }
 };

 // Create a Razorpay instance using options object
 const rzp = new Razorpay(options);

 // Open Razorpay checkout form
 rzp.open();

Testing the Integration and Verifying the Payment Status:

In this section, we will test our integration by making a payment using a test card and verifying the payment status and the signature from the Razorpay server. We will also check the dashboard for the payment details and logs. We will also handle errors and exceptions in our code.

To test our integration by making a payment using a test card, we need to run our NodeJS server and open our index.html file in our browser. We can then click on the pay button and fill in the details of a test card provided by Razorpay. We can also enter any name, email, and contact number. We can then click on the pay button and complete the payment process. We should see a success message on the Razorpay checkout form and an alert on our browser with the payment status.

To verify the payment status and the signature from the Razorpay server, we need to use the handler function in our JavaScript code to capture the payment id from the response and send it to our express server. We can then use the razorpay.payments.capture method in our express server to capture the payment with the payment id and get a payment object in return. We can then check the status property of the payment object to see if it is "captured" or not. We can also use the callback_url option in our JavaScript code to specify a URL where the Razorpay server will send a POST request with the payment details after the payment is completed. We can then use the razorpay.utils.validateWebhookSignature method in our express server to verify the signature from the Razorpay server with the payload, signature, and secret and get a boolean value in return.

Conclusion:

In this blog post, we have learned how to integrate Razorpay with NodeJS and create a simple and secure online payment system for our website. We have seen how to use the Razorpay APIs and SDKs to create orders, capture payments, and verify signatures. We have also seen how to use the Razorpay checkout script to display a customized payment form and handle the payment events. We have also tested our integration using a test card and checked the dashboard for the payment details and logs. We have also handled some errors and exceptions in our code using try-catch blocks or promise catch methods.

Razorpay is a great solution for online payments as it supports multiple payment modes, currencies, and international payments. It also handles all the complexities and risks involved in online payments and provides a seamless and hassle-free experience for both developers and customers. Nodejs is a fast, scalable, and easy-to-use technology that allows us to create web servers and applications using JavaScript. However, it also has some drawbacks such as callback hell, error handling, etc.

I hope you enjoyed this tutorial and learned something new. If you have any questions or feedback, please feel free to leave a comment below or contact me on Twitter or LinkedIn. You can also check out the official documentation of Razorpay or some of the tutorials available online for more details. Thank you for reading!

3
Subscribe to my newsletter

Read articles from Dani Ram Sahu directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Dani Ram Sahu
Dani Ram Sahu

I'm a MERN stack developer, who is exploring technical writting