Integrating Payment Gateways in MERN Applications
Tags: webdev, javascript, react, node
Published: 2023-05-21 21:08:26

In this article, we will be learning about integrating payment gateways in MERN applications as payment options that need to be available for the sake of e-commerce support.

There can be suitable options for payments such as Razorpay or Stripe. Let us get started with the tutorial:-

**Working of Payment Gateway**
Firstly, we understand how the payment mechanism works in MERN Stack along with an illustration. 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pnt1z4ke0h3avn8hf3uj.png)

When a user clicks on the Buy Option on an E-Commerce website, the product ID is passed to the server, the product price is checked and sent to the Razorpay API and an order ID is generated in the response. 

The order ID is passed for the confirmation of the order. Upon completion of payment, Razorpay generates Payment ID, Order ID, Timestamp and Signature.


The details generated are verified on our server to make sure the payment is completed successfully.

### Easy Steps to Integrate Payment Gateway using MERN

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nucizk3sj24y5g6dgjnc.png)

1. The first step is to create a Razorpay account where you can sign yourself up or log in to your existing email filling up the necessary details until the Razorpay dashboard pops up on your screen. 

2. Keep in mind that if you are doing it for learning purposes, select Test Mode from Top Right.
 
3.  Head over to Settings~>API Keys~> Generate Test Keys. 
 
4. Once the keys are generated, copy and paste them into a blank text/document file and minimize the file.
 
5. Open command-> Create folder and cd folder navigate to the folder. Once we are done performing this, we create a folder named ‘server’ by writing ‘mkdir server’ and navigate inside.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kxf9liefcrt1oez2cwe3.png)

6. Next, to create the node app we fire the command npm init which creates your web app with settings.

7. Later the npm i express dotenv razorpay cors command is written to install all the dependencies required for integrating the payment gateways app. 

8. Now you can open the folder in vscode by writing ‘. code’.
Now we have to create an index file that we will import the necessities and work on routing. 

9. The code given below can help you in integrating payment gateways into your MERN application.

```

const express = require("express");
const cors = require("cors");
const dotenv = require("dotenv");
const paymentRoute = require("./routes/payments");
//Initialize App
const app = express();


// Setting up enivronment variables
dotenv.config();

//Middlewares
app.use(express.json());
app.use(cors());

//Routing
app.use("/api/payment/",paymentRoute);

//Listening App
const port = process.env.PORT || 8080;
app.listen(port,()=> console.log(`Listening port ${port}`));

```

Now we will be creating a folder named routes in the root directly that comes in handy in importing the payment file. The payment file consists of the two APIs that are required for creating the order and verifying the order. 

The given snippet explains the following:- 

```
const router = require("express").Router();
const Razorpay = require("razorpay");
const crypto = require("crypto");

//Creating Order
router.post("/orders",async(req,res) => {
    try {
        const instance = new Razorpay({
            key_id: process.env.KEY_ID,
            key_secret: process.env.KEY_SECRET,
        });

        const options = {
            amount: req.body.amount * 100,
            currency:"INR",
            receipt:crypto.randomBytes(10).toString("hex"),
        }
        instance.orders.create(options,(error,order) => {
            if(error) {
                console.log(error);
                return res.status(500).json({message:"Something Went Wrong!"});
            }
            res.status(200).json({data:order});
        });

    } catch(error) {
        console.log(error);
        res.status(500).json({message:"Internal Server Error!"});
    }

});

//Verifying the payment
router.post("/verify",async(req,res) => {
    try {
        const {
            razorpay_orderID,
            razorpay_paymentID,
            razorpay_signature } = req.body;
        const sign = razorpay_orderID + "|" + razorpay_paymentID;
        const resultSign = crypto
        .createHmac("sha256",process.env.KEY_SECRET)
        .update(sign.toString())
        .digest("hex");

        if (razorpay_signature == resultSign){
            return res.status(200).json({message:"Payment verified successfully"});
        }

    } catch(error) {
        console.log(error);
        res.status(500).json({message:"Internal Server Error!"});
    }
});

module.exports = router;
```
We have successfully completed the backend portion of our app. Now create a react app in our root folder with npx create-react-app payapp  and install axios by npm i axios for calling APIs.

**Setting up the Front End for our Web App**

Once we are done with the backend portion, we will switch to the creation of the front end which is going to be a sample e-commerce shoe store.

Open React App in your preferred code editor and paste this checkout page link as a script in index.html ->https://checkout.razorpay.com/v1/checkout.js

On setting up with our react app, we implement useState in react to create a shoe sample for our payment integration with Razorpay. The code looks something like this for App.js.

```
import axios from "axios";
import {useState} from "react";
import "./App.css";

function App() {
  const [shoe,setShoe] = useState({
    name: "Training Shoes",
    creator: "Nike",
    img: "https://images.pexels.com/photos/3490360/pexels-photo-3490360.jpeg?auto=compress&cs=tinysrgb&dpr=1&w=500",
    price: 500,
});

const initPay = (data) => {
  const options = {
    key : "************************",
    amount: data.amount,
    currency: data.currency,
    name: shoe.name,
    description: "Test",
    image:shoe.img,
    order_id: data.id,
    handler: async (response) => {
      try {
        const verifyURL = "https://localhost:8080/api/payment/verify";
        const {data} = await axios.post(verifyURL,response);
      } catch(error) {
        console.log(error);
      }
    },
    theme: {
      color: "#3399cc",
    },
  };
  const rzp1 = new window.Razorpay(options);
  rzp1.open();
};

const handlePay = async () => {
  try {
    const orderURL = "https://localhost:8080/api/payment/orders";
    const {data} = await axios.post(orderURL,{amount: shoe.price});
    console.log(data);
    initPay(data.data);
  } catch (error) {
    console.log(error);
  }
};

  return(
  <div className="App">
    <div className="shoe_container">
      <img src={shoe.img} alt="shoe_img" className="shoe_img" />
      <p className="shoe_name">{shoe.name}</p>
      <p className="shoe_creator">By {shoe.creator}</p>
      <p className="shoe_price">Price: {shoe.price}</p>
      <button onClick={handlePay} className="buyBtn">Buy Shoes</button>
    </div>
  </div>
  );
}

export default App;
```
On applying styling to the className in App.css, the sample frontend looks something like this with the handlePay async function calling the API and making the integrating payment gateways in MERN application successful.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fepswhedrhc8s14aezsg.png)

Finally, we go to the terminal in the node project folder and node index.js, in the result of which if we click on buy now, we get an integrated payment gateway somewhat like this.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/my0m6jzh6a6xp2lqigpg.png)