How To Integrate Razorpay Payment Gateway With Next.js App - V13.2

  • Posted on September 20, 2023
  • Technology
  • By MmantraTech
  • 3445 Views

In the world of e-commerce and online services, providing a seamless and secure payment experience is essential. Razorpay is a popular payment gateway that enables businesses to accept online payments easily. If you're building your web application with Next.js, integrating Razorpay can be a powerful addition. In this guide, we'll walk you through the process of integrating Razorpay into your Next.js application to enable secure and efficient payments.

Razor-i0QDVCSkag.png

Prerequisites

Before we dive into the integration process, make sure you have the following prerequisites:

  1. Razorpay Account: If you don't already have a Razorpay account, sign up for one at Razorpay.

  2. Node.js: Ensure you have Node.js installed on your development machine. You can download it from the official Node.js website.

  3. Next.js Project: Create a Next.js project if you haven't already. You can do this using the following command:12

    npx create-next-app@latest razor-pay-integration

Now, let's proceed with the integration steps:

Step 1: Install Required Packages

To work with Razorpay in your Next.js application, you'll need to install the necessary npm packages. Open your project directory in the terminal and run the following command:

 

npm install razorpay

 

This will install the Razorpay package, allowing you to interact with Razorpay services.

Step 2: Generate API Keys

After creating your Razorpay account, navigate to the "Settings" section and find the "API Keys" tab. Generate your API key and secret key, which you'll use for authentication in your application.

Step 3: Set up Environment Variables

To keep sensitive information like API keys secure, store them in environment variables. Create a .env.local file in your Next.js project's root directory and add your Razorpay API keys like this:

RAZORPAY_KEY_ID=your_api_key
RAZORPAY_KEY_SECRET=your_secret_key

 

 

Let's do payment integration next. JS Step by Step:

Step 1:

Create a file ".env.local" at the root of the project. Add the below code to that file. Make sure you add your keys from the Razorpay account.

 

MONGO_URI = "mongodb://127.0.0.1:27017/razor"
RAZORPAY_API_KEY= <Key>
RAZORPAY_APT_SECRET=<Secret>

NOTE: Env file in Next.js is automatically loaded (NODE Env default), so you don't need to install any extra packages

 

Step 2:

Create a file a folder "src/components/razorpay" (I assume you have an "app" directory inside the "src" folder).

Create a file "Buy.jsx" inside the Razorpay folder and the below code :

"use client"
import React,{useState} from "react";

const Buy = ({ makePayment }) => {

  const [isLoading, setIsLoading] = useState(false);



  return (
    <div className="flex flex-col items-center justify-center mt-[100px]">

<h1 className="text-2xl">Razor Pay Integration with NextJs 13</h1>
<button
     onClick={() => {
          makePayment({ productId: "example_ebook" });
        }}
      disabled={isLoading}
      className={`bg-blue-500 text-white font-semibold mt-20 py-2 px-4 rounded ${
        isLoading ? 'opacity-50 cursor-not-allowed' : ''
      }`}
    >
      {isLoading ? 'Processing...' : 'Buy Now'}
    </button>



    </div>
  );
};

export default Buy;

 

Create a file "BuyProduct.jsx" inside the Razorpay folder with the code below:

 

"use client";
import React, { Suspense } from "react";
import Buy from "./Buy";
import { useRouter  } from 'next/navigation';
import Loading from "@/app/loading";


const BuyProduct = () => {

  const router = useRouter()


  const makePayment = async ({ productId = null }) => {
    // "use server"
    const key = process.env.RAZORPAY_API_KEY;
    console.log(key);
    // Make API call to the serverless API
    const data = await fetch("http://localhost:3005/api/razorpay");
    const { order } = await data.json();
    console.log(order.id);
    const options = {
      key: key,
      name: "mmantratech",
      currency: order.currency,
      amount: order.amount,
      order_id: order.id,
      description: "Understanding RazorPay Integration",
      // image: logoBase64,
      handler: async function (response) {
        // if (response.length==0) return <Loading/>;
        console.log(response);

        const data = await  fetch("http://localhost:3005/api/paymentverify", {
          method: "POST",
          // headers: {
          //   // Authorization: 'YOUR_AUTH_HERE'
          // },
          body: JSON.stringify({
            razorpay_payment_id: response.razorpay_payment_id,
            razorpay_order_id: response.razorpay_order_id,
            razorpay_signature: response.razorpay_signature,
          }),
        });



        const res = await data.json();

        console.log("response verify==",res)

        if(res?.message=="success")
        {


          console.log("redirected.......")
          router.push("/paymentsuccess?paymentid="+response.razorpay_payment_id)

        }

        // Validate payment at server - using webhooks is a better idea.
        // alert(response.razorpay_payment_id);
        // alert(response.razorpay_order_id);
        // alert(response.razorpay_signature);
      },
      prefill: {
        name: "mmantratech",
        email: "mmantratech@gmail.com",
        contact: "9354536067",
      },
    };

    const paymentObject = new window.Razorpay(options);
    paymentObject.open();

    paymentObject.on("payment.failed", function (response) {
      alert("Payment failed. Please try again. Contact support for help");
    });
  };

  return (
    <>
    <Suspense fallback={<Loading/>}>
      <Buy makePayment={makePayment} />
      </Suspense>
    </>
  );
};

export default BuyProduct;

 

NOTE : Don't forget to put the Razorpay script in the "layout.js" file, as it is responsible for opening the Razorpay popup. 

Open file  "app/layout.js" and put following code: 

import './globals.css'
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
import Script from 'next/script'



export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default function RootLayout({ children }) {
  return (
    <>
    <html lang="en">
      <body className={inter.className}>{children}</body>
    </html>
    <Script src="https://checkout.razorpay.com/v1/checkout.js"
          />

    </>
  )
}

Step 3:

Create a folder "database" inside the src directory and create a file "database.js" inside the database folder:

Put the below code in the database. js file 

import mongoose from "mongoose";

//you can more details on mmantratech.com
//youtube : techmalasi
 const MONGODB_URI = process.env.MONGO_URI;

if (!MONGODB_URI) {
  throw new Error(
    'Something went wrong'
  )
}
let cached = global.mongoose

if (!cached) {
  cached = global.mongoose = { conn: null, promise: null }
}

async function dbConnect () {
  if (cached.conn) {
    return cached.conn
  }

  if (!cached.promise) {
    const opts = {
      useNewUrlParser: true,
      useUnifiedTopology: true
    }

    cached.promise = mongoose.connect(MONGODB_URI,opts).then(mongoose => {
      console.log("You successfully Connected")
      return mongoose
    })
  }
  cached.conn = await cached.promise
  return cached.conn
}

export default dbConnect

 

Create a folder "model" inside the database folder and create the below files and put the code .

Payment.js

import mongoose from "mongoose";

const paymentSchema = new mongoose.Schema({
  razorpay_order_id: {
    type: String,
    required: true,
  },
  razorpay_payment_id: {
    type: String,
    required: true,
  },
  razorpay_signature: {
    type: String,
    required: true,
  },
});

// export const Payment = mongoose.model("Payment", paymentSchema);

module.exports = mongoose.models.Payment || mongoose.model('Payment', paymentSchema)

User.js

// models/User.js

import mongoose from 'mongoose'

const UserSchema = new mongoose.Schema({
  name: String,
  email: String
})

module.exports = mongoose.models.User || mongoose.model('User', UserSchema)

STEP 4: 

Now it's time to create Next.js Route Handlers (>=V13.2) to create restful API routes. You must know that in NEXT.js there is no need to create an extra Server as Node and Routes hanlers are default with the Next.js framework.

 

You have to follow above screenshot and your file/folder structure should look like above

NOTE : In Next.js  >= V13.2 API Routes are shifted to the APP directory, and routes are decided by the folder you create, and Next.js checks a special file, "route.js," and decides to redirect. So you have to create "route.js" in every folder explaining request type (GET, POST)

Create a file "route.js" inside paymentverify and put below code

import { NextResponse } from "next/server";
import Razorpay from "razorpay";
import shortid from "shortid";
import crypto from "crypto";
import Payment from "../../../database/model/Payment"
import dbConnect from '../../../database/database'
const instance = new Razorpay({
    key_id: process.env.RAZORPAY_API_KEY,
    key_secret: process.env.RAZORPAY_APT_SECRET,
  });

export async function POST(req,res) {

    const { razorpay_order_id, razorpay_payment_id, razorpay_signature } =
  await req.json();
   const body = razorpay_order_id + "|" + razorpay_payment_id;
console.log("id==",body)

 const expectedSignature = crypto
   .createHmac("sha256", process.env.RAZORPAY_APT_SECRET)
   .update(body.toString())
   .digest("hex");

const isAuthentic = expectedSignature === razorpay_signature;


 if (isAuthentic) {

  console.log(Payment)

  await dbConnect()

   await Payment.create({
     razorpay_order_id,
     razorpay_payment_id,
     razorpay_signature,
   });

  //  return NextResponse.redirect(new URL('/paymentsuccess', req.url));

} else {
    return NextResponse.json({
        message: "fail"
      }, {
        status: 400,
      })

}


return NextResponse.json({
    message: "success"
  }, {
    status: 200,
  })

}

Create a file "route.js" inside razorpay folder and put below code

import { NextResponse } from "next/server";
import Razorpay from "razorpay";
import shortid from "shortid";

const instance = new Razorpay({
    key_id: process.env.RAZORPAY_API_KEY,
    key_secret: process.env.RAZORPAY_APT_SECRET,
  });


export async function GET() {

    const payment_capture = 1;
    const amount = 1 * 100 // amount in paisa. In our case it's INR 1
    const currency = "INR";
    const options = {
        amount: (amount).toString(),
        currency,
        receipt: shortid.generate(),
        payment_capture,
        notes: {
            // These notes will be added to your transaction. So you can search it within their dashboard.
            // Also, it's included in webhooks as well. So you can automate it.
            paymentFor: "testingDemo",
            userId: "100",
            productId: 'P100'
        }
    };

   const order = await instance.orders.create(options);
  return NextResponse.json({ msg: "success",order });
}


export async function POST(req) {
  const body = await req.json();


  return NextResponse.json({ msg: body });
}

 

Create a file "route.js" inside user Folder and put below code

import { NextResponse } from "next/server";
import dbConnect from '../../../database/database'
import User from '../../../database/model/User'

export async function GET() {

//   await dbConnect();

  return NextResponse.json({ msg: "success" });
}


export async function POST(req) {
  const body = await req.json();
   await dbConnect();
  const user = await User.create(body)

  return NextResponse.json({ msg:"success",data: user });
}

 

NOTE : API Diretory in App folder decides Routes Handlers in Next.js >= 13.2 Version

Congratulations you have created below routes which will be used while payment via RazorPay

STEP 6:

Create a folder paymentsuccess as above and create two files, "page.js" and "success.jsx."

page.js

import React from 'react'
import Success from './Success'

export default function page(){


  return (
    <>
      <Success/>
    </>
  )
}

 

Success.jsx

"use client"
import React from 'react'
import { useSearchParams } from 'next/navigation'


const Success = () => {
    const searchParams = useSearchParams()
    const paymentid = searchParams.get('paymentid')


  return (
    <div className="flex flex-col items-center justify-center mt-[100px]">
    <div className="bg-green-100 border border-green-400 w-1/2 text-green-700 px-4 py-3 rounded relative" role="alert">
 <strong className="font-bold">Payment successful!</strong>
 <span className="block sm:inline">Your paymentID= {paymentid} has been processed.</span>
 <span className="absolute top-0 bottom-0 right-0 px-4 py-3">
   <svg
     className="fill-current h-6 w-6 text-green-500"
     role="button"
     xmlns="http://www.w3.org/2000/svg"
     viewBox="0 0 20 20"
   >
     <title>Close</title>
     <path
       d="M14.293 5.293a1 1 0 011.414 1.414L11.414 10l4.293 4.293a1 1 0 11-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.293a1 1 0 111.414-1.414L10 8.586l4.293-4.293z"
       fillRule="evenodd"
       clipRule="evenodd"
     />
   </svg>
 </span>
</div>

</div>
  )
}

export default Success

STEP 6:

Now it's time to call everything from the home page. Ins, the home route is always app/page.js. So open file "app/page.js" and put the code below.

import BuyProduct from '@/components/razorpay/BuyProduct'
import Image from 'next/image'


export default function Home() {
 return(
  <>
    <BuyProduct/>
  </>
 )
}

 

Okay guys you have followed above steps I am certainly sure that you would be able to pay payment via Razorpay. Now it's time to run the project.

 

 

After running the Next.js app in the browser, your screen should look like below:

 

 

If you have gotten above the screen, then congratulations, guys, you have followed all steps successfully. Please find below testing card details and go further.

Visa 4111 1111 1111 1111 Random CVV Any future date

 

More  you can find in my youtube channel 

https://www.youtube.com/channel/UC9HIIz8gI5oOK92BctimlRw

 

Conclusion,

I hope I was able to explain all practical steps. Guys, one thing I need to add here is that I have not explained the code part, hoping all already know it next. JS basic very well. However, if you still have problems, please comment or go to the YouTube channel to get every step.

 

 

 

 

1
Author
No Image
Admin
MmantraTech

Mmantra Tech is a online platform that provides knowledge (in the form of blog and articles) into a wide range of subjects .

You May Also Like

Write a Response