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.

Prerequisites
Before we dive into the integration process, make sure you have the following prerequisites:
-
Razorpay Account: If you don't already have a Razorpay account, sign up for one at Razorpay.
-
Node.js: Ensure you have Node.js installed on your development machine. You can download it from the official Node.js website.
-
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
- http://localhost:3005/api/paymentverify
-
http://localhost:3005/api/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.
Write a Response