Open In App

Razorpay Payment Integration using Node.js

Last Updated : 10 Nov, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Payment gateway is a technology that provides online solutions for money-related transactions, it can be thought of as a middle channel for e-commerce or any online business, which can be used to make payments and receive payments for any purpose.

Sample Problem Statement: This is a simple HTML page where we have a button to pay an amount of Rupees 499.00. Eventually, the user will click on that button and somehow we want to receive that amount and after that, we can decide how we will give the access of course, but that’s not the part of the discussion for our article. 

 

Approach: Razorpay is one of the popular payment gateways, it gives us access to all payment modes including credit card, debit card, net banking, UPI, and also other wallets i.e airtel money, payZapp, etc. It also provides a dashboard where all activity can be monitored. It can be integrated with any online application and makes it much easier for online businesses to interact with customers, Razorpay helps us in providing & processing all essential functionality, Here we’ll discuss how we can achieve this if the backend of our application is in NodeJS.

Diagrammatic flowchart of communication between Servers and Frontend 

This is the basic diagram of how all internal things are interacting among them, if every step from 1 to 8 succeeded then we will successfully be able to achieve our goal. From steps 1 to 4 we are creating order and receiving the response and then from 5 to 6, we are receiving payment for that order and at the last two steps, we are verifying the authenticity of the response whether it came from the Razorpay server or not. 
The arrows are designed according to time. 

Step by Step Implementation:

Step 1: First of all write this command in your terminal, to create a nodejs application.

npm init

This will ask you for few configurations about your project you can fill them accordingly, also you can change it later from the package.json file. Then create an app.js file for the backend server and an index.html file for the frontend.

Step 2: Now, Install required Modules

npm install express         //To run nodejs server 
npm install razorpay        //To use razorpay utilities

Project Structure: It will look like the following.

Step 3: As you want to access the Razorpay APIs you must need keys, Hence Go to Razorpay and register yourself and then visit the settings in the dashboard section, Click on Generate API Keys, and then you will get your key_id and key_secret through which you can get your Razorpay instance.

Step 4: Import Razorpay and create a new instance of Razorpay, this instance is necessary to access any of the resources from Razorpay. Provide an object containing key_id and key_secret to the constructor.

Below is the basic initial code implementation for the backend and frontend.

App.js




// Inside app.js 
const express = require('express');
const Razorpay = require('razorpay'); 
  
// This razorpayInstance will be used to
// access any resource from razorpay
const razorpayInstance = new Razorpay({
  
    // Replace with your key_id
    key_id: rzp_test_fiIwmRET6CApc2,
  
    // Replace with your key_secret
    key_secret: YAEUthsup8SijNs3iveeVlL1
});
  
const app = express();
const PORT = process.env.PORT || '5000';
  
// Here we will create two routes one 
// /createOrder and other /verifyOrder 
// Replace these comments with the code 
// provided later in step 2 & 8 for routes
  
app.listen(PORT, ()=>{
    console.log("Server is Listening on Port ", PORT);
});


index.html




<!-- Inside index.html -->
<!DOCTYPE html>
<html lang="en">
  
<head>
    <meta charset="utf-8" />
    <meta content=
        "This is a demo of Web integration 
        of Razorpay in NodeJS" 
        author="Mr. Twinkle Sharma" />
    <title>Razorpay Web-Integration</title>
</head>
  
<body>
    <hr/>
    <h2>Advanced Data Structures & Algorithms Course</h2>
    <h3>Description</h3>
  
    <ul>
        <li>Best Course for SDE placements</li>
        <li>
            Available in 4 major Languages JAVA, 
            C/C++, Python, Javascript
        </li>
        <li>Lifetime Access</li>
    </ul>
  
    <span> Cost:- 499 Rupees 
        <button id="pay-button" >
            Pay Now & Get Access
        </button
    </span>
    <hr/>
  
    <!-- Processing Payment Checkout -->
    <!-- We will write code for payment here, 
        Replace this comment with the code we 
        are explaining below in step 5 of the 
        article -->
</body>
  
</html>


Step 5: Sending order information from Frontend to Our NodeJS Server. 

Create a route inside the app.js to receive data of order from user requests, here we are using express because it is more simple and is used by many developers. We have set up our ‘/createOrder’ route at our nodejs server app.js to receive data from the client and we are sending the order data from ‘req. body’. 
Just to keep things simple here Postman has been used as a client, you can easily send post requests from the frontend in your own way.

Note: Make sure to successfully run the server every time before interacting with it. 

Step 6: Sending order information from Our NodeJS Server to Razorpay Server.

We have order information extracted from the req.body at our server, now we have to send it to the Razorpay server for further proceedings. The razorpayInstance which we’ve created earlier will be used to access orders API from Razorpay and create is a method that creates an order, it takes two parameters, the first is an options object and the other is the callback function which later provides us response as either error in case of failure or order on success.

App.js




//Inside app.js
app.post('/createOrder', (req, res)=>{ 
  
    // STEP 1:
    const {amount,currency,receipt, notes}  = req.body;      
          
    // STEP 2:    
    razorpayInstance.orders.create({amount, currency, receipt, notes}, 
        (err, order)=>{
          
          //STEP 3 & 4: 
          if(!err)
            res.json(order)
          else
            res.send(err);
        }
    )
});


Step 7: Receiving order response from Razorpay to our NodeJS server.

After then, Razorpay server processes the received data and sends the order response from its server, here we are merging the step 3 and 4 because separating them in such a little project makes no sense, separation can be useful when you will work with a real database and enough big project. Below is the successfully returned response from the Razorpay server. 

Explanation:

We have received a JSON as a response from the Razorpay server, with a status code 200, which means everything is ok and the order has been created successfully. The description of JSON is below:

id: A unique order id, will be used during payment.
entity: It is an abbreviation to show that the response corresponds to any order.
amount: Total Amount of order, in Subunit of currency.
amount_paid: Amount paid from order, it is used when you have partial payments.
amount_due: Total Amount – Partially paid amount.
currency: Currency of Amount, check the whole list of supported currencies here.  
receipt: It is the receipt of the order.
offer_id: Used to avail some offer, it is used when you have some discounts or special offer on order.
status: It is the status of the order for ex- order may be created, attempted or paid.
attempts: Total number of attempts user made for payment.
notes: This is a simple object for additional information.
created_at: It is the time when an order was created and in UNIX time format. 

Below is the created order at Razorpay Dashboard and status created means the order is just been created, it will become attempted if any further payments on this failed and paid if succeeded.   

Note:- We are handling all the initial processes at a single API endpoint ‘/createOrder‘ but as soon as the project grows it is good to separate all the things as needed.  

Step 8: Sending request from Frontend to Razorpay Server for payment capture.

Now as we have created an order we can proceed to checkout to receive the amount. Below is the snippet provided by Razorpay to use inside index.html, It handles everything itself, from rendering a Modal UI in the frontend to processing payment checkout at its backend, The things it requires are some configurations, banking/wallet related credentials & Order ID along with the request.

index.html




<!--Inside index.html -->
<script>
   var options = {
       "key": "rzp_test_fiIwmRET6CApc2", 
       "amount": "49900", 
       "currency": "INR",
       "name": "Dummy Academy",
       "description": "Pay & Checkout this Course, Upgrade your DSA Skill",
                  20210806114908/dummy-200x200.png",
       "order_id": "order_HdPuQW0s9hY9AU",  
       "handler": function (response){
           console.log(response)
           alert("This step of Payment Succeeded");
       },
       "prefill": {
          //Here we are prefilling random contact
         "contact":"9876543210", 
           //name and email id, so while checkout
         "name": "Twinkle Sharma",  
         "email": "smtwinkle@gmail.com"  . 
       },
      "notes" : {
         "description":"Best Course for SDE placements",
         "language":"Available in 4 major Languages JAVA, 
                     C/C++, Python, Javascript",
         "access":"This course have Lifetime Access"
       }, 
       "theme": {
           "color": "#2300a3"
       }
   };
   var razorpayObject = new Razorpay(options);
   console.log(razorpayObject);
   razorpayObject.on('payment.failed', function (response){
         console.log(response);
         alert("This step of Payment Failed");
   });
     
   document.getElementById('pay-button').onclick = function(e){
       razorpayObject.open();
       e.preventDefault();
   }
</script>


Explanation:

The first script tag is loading a js file from the Razorpay server. It has some code inside it, which is responsible for executing this whole code snippet. In the second script tag, we are creating an object which later will be sent to the Razorpay server to proceed with payment.
This is the description of the options, the fields with * are required and others are optional which have their default value at the Razorpay server.   

1. key: Your Razorpay key_id which you’ve got from the dashboard.
2. amount: Amount to be paid.
3. currency: Currency string of three characters.
4. Name: Name of company, it will be shown on UI modal. 
5. order_id: Must be valid order id generated from Razorpay, we will use the one which we have created earlier.
6. description: Just a simple description of the purchase, it will also be shown in the modal. 
7. image: Link of Logo, must be min dimension 256×256 & max size 1MB, of Company to be shown on modal, in our example case we are using a dummy logo.
8. handler: It is a function that will get executed on successful payment, we are simply doing alert and console log, but it can be modified very easily to customize functionality. 
9. theme: A object which can be used to set the theme of modal according to your Application UI, for ex- you can set color and backdrop_color using HEX code.
10. prefill: Details which you want to prefill when UI will be rendered, ex- You can prefill the email and name so that it will not be asked from the user, Also if somehow you can know the history of a user, you can prefill the modes of payment based on his preference.
11. notes: This is a simple object for additional information.

Razorpay have more option than used here, you can customize your application according to them. Now after all of this, we call the Razorpay function which is declared in the file included by the first script tag, it takes an object as a parameter and returns a Razorpay object which will have some predefined and some user-defined functionalities, that’s why Razorpay was asking for our configured options. Let’s have a look at what we’ve got from there use console.log to view these details.

We have got a lot of data as a return like, the modal which is going to render on-screen after we click on button associated with that, the function registered for event ‘payment.failed’ which we will later see how we can use it, the id and also other required things. Now coming back to the code explanation, after getting the Razorpay object we have registered a callback function which we are executing on the event ‘payment.failed‘, and this is configured by Razorpay. Subsequently, we have used a basic web API to get element by id, which selects the button associated with that id and executes a function. razorpayObject.open(); opens a window that accommodates a modal that includes all essential functionalities to make checkout.    
e.preventDefault(); prevents the default configurations of browser for events. 

Output:

 

Explanation of above output:

  • User clicks on the button associated with payment
  • A Modal, provided by Razorpay opens in the middle of the window, did you notice the company name, the description, the logo we have set before sending the request has been rendered here, also the contact number and email are prefilled.
  • Even if we have prefilled some details also then we have access to change them during the proceeding to payment.
  • After then, we can proceed to payment, let say we have chosen the card method, Here we have entered a dummy card detail “Card Number 4111 1111 1111 1111” expiry date can be any future month/year, CVV can be any three-digit number, also the name of the cardholder is prefilled here, but you can edit it before proceeding.
  • Then Immediately, Razorpay will process the payment.
  • After completion once again Razorpay asks for your permission whether to do payment or not, click on success for proceeding payment or click on failure to deny.

Step 9: Receiving payment response from Razorpay to the Frontend.

After successful step 8, we will receive a response from Razorpay which includes the payment id, signature, order id, etc at the frontend. Otherwise, the response will be of failure along with some reasons for failure. Below is the console.log of the successfully returned response.   

Step 10: Sending Payment response from the frontend to our NodeJS server

We have created a ‘/verifyOrder’ API endpoint at our server to receive payment data. Postman is used here to send data as a client, you can send post requests of data in your own way. 
The signature which was received from the payment response has been sent through the custom header “x-razorpay-signature”, putting “x-”  before the header name is the convention and The payment_id and order_id have been sent from the request body.

Step 11: Verifying authenticity and sending a corresponding response to the User 

Although we have captured the payment we can’t send a response to the user without verification. So this is the verification step, as you know we have got several things like razorpay_payment_id, razorpay_order_id, razorpay_signature, and some other information on successful payment. Now how would you get to know that this information corresponds to a valid payment and it must have been captured in your Razorpay dashboard? Because there may be some cases when somehow anyone can send the fake response and you will be considering that payment as captured.  Hence, for verification, Create a signature in your server using the order_id on which payment has been done and the razorpay_payment_id returned from the response, also in this step, you’ll need the key_secret which you’ve got earlier from the dashboard while generating API keys.

Now use the  SHA256 algorithm, it is a cryptographic function that receives some arguments and returns a crypto hash which later can be used to verify something based on the secret code given as an argument. Construct an  HMAC hex digest according to predefined Razorpay syntax:

generated_signature = HMAC-SHA256(order_id + "|" + razorpay_payment_id, secret);
//HMAC-SHA256:- This is just a naming convention, HMAC-X means the X cryptographic 
//function has been used to calculate this hash 

if (generated_signature === razorpay_signature) {
   //payment is successful, and response has been came from authentic source. 
}

Note: – If your application is big enough and you don’t want to do this for verification every time, there is a simple way of setting webhook(webhook is a way to send information to another application based on the events that occurred in realtime) at Razorpay dashboard, you can explore it.

app.js




//Inside app.js
app.post('/verifyOrder',  (req, res)=>{ 
      
    // STEP 7: Receive Payment Data
    const {order_id, payment_id} = req.body;     
    const razorpay_signature =  req.headers['x-razorpay-signature'];
  
    // Pass yours key_secret here
    const key_secret = YAEUthsup8SijNs3iveeVlL1;     
  
    // STEP 8: Verification & Send Response to User
      
    // Creating hmac object 
    let hmac = crypto.createHmac('sha256', key_secret); 
  
    // Passing the data to be hashed
    hmac.update(order_id + "|" + payment_id);
      
    // Creating the hmac in the required format
    const generated_signature = hmac.digest('hex');
      
      
    if(razorpay_signature===generated_signature){
        res.json({success:true, message:"Payment has been verified"})
    }
    else
    res.json({success:false, message:"Payment verification failed"})
});


Output: 

This is the response which we have got from our verifyOrder API, because our payment was genuine it is returning a successful response, with a  status code 200 means everything is OK.  

Now that’s all, with this we have successfully created an order, received payment, and verified authenticity. 
This is the payment and order ledger showing on the dashboard, the status captured means we have received payment successfully, and paid means the amount of order has been paid.

You may have noticed that we are separately doing all things, it is just to explain how these things are working independently, you can easily combine all of them to work around with real-world projects. Also, keep a note, Razorpay has lots of API endpoints that you can use to customize your eCommerce application.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads