Why Razorpay Is the Default Payment Gateway for Indian React Apps in 2026 If you are building a React or Next.js app for the Indian market in 2026, Razorpay is
Get a free consultation from our team. We build websites, mobile apps, AI chatbots, and custom software for businesses across India.
Stay in the loop with everything you need to know.
If you are building a React or Next.js app for the Indian market in 2026, Razorpay is almost certainly the right payment gateway. It supports UPI, cards, netbanking, wallets, EMI, and international payments — and its developer experience is the best of any Indian payment provider. This guide walks through a complete, production-ready integration from zero to live, with code you can copy into your project today.
By the end of this tutorial, you will have a working checkout that:
In your Next.js project, install the server SDK:
npm install razorpay
The frontend loads the Razorpay checkout script dynamically — no npm package needed.
Create or update .env.local:
RAZORPAY_KEY_ID=rzp_test_xxxxxxxxxxxx
RAZORPAY_KEY_SECRET=xxxxxxxxxxxx
NEXT_PUBLIC_RAZORPAY_KEY_ID=rzp_test_xxxxxxxxxxxx
The NEXT_PUBLIC_ prefix exposes the Key ID to the browser — which is safe. The Secret stays server-only.
Create app/api/razorpay/order/route.ts:
import { NextResponse } from 'next/server';
import Razorpay from 'razorpay';
const razorpay = new Razorpay({
key_id: process.env.RAZORPAY_KEY_ID!,
key_secret: process.env.RAZORPAY_KEY_SECRET!,
});
export async function POST(req: Request) {
const { amount, currency = 'INR', receipt } = await req.json();
const order = await razorpay.orders.create({
amount: amount * 100, // paise
currency,
receipt,
});
return NextResponse.json(order);
}
On your frontend (for example components/CheckoutButton.tsx):
"use client";
import { useState } from "react";
declare global {
interface Window { Razorpay: any; }
}
export default function CheckoutButton({ amount }: { amount: number }) {
const [loading, setLoading] = useState(false);
const loadScript = (src: string) =>
new Promise((resolve) => {
const s = document.createElement("script");
s.src = src;
s.onload = () => resolve(true);
s.onerror = () => resolve(false);
document.body.appendChild(s);
});
const handlePayment = async () => {
setLoading(true);
const ok = await loadScript("https://checkout.razorpay.com/v1/checkout.js");
if (!ok) { alert("Razorpay SDK failed to load"); setLoading(false); return; }
const res = await fetch("/api/razorpay/order", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ amount, receipt: `rcpt_${Date.now()}` }),
});
const order = await res.json();
const options = {
key: process.env.NEXT_PUBLIC_RAZORPAY_KEY_ID,
amount: order.amount,
currency: order.currency,
name: "Your Business Name",
description: "Order Payment",
order_id: order.id,
handler: async (response: any) => {
const verify = await fetch("/api/razorpay/verify", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(response),
});
const data = await verify.json();
if (data.ok) alert("Payment successful!");
else alert("Payment verification failed.");
},
theme: { color: "#6A27FF" },
};
const rzp = new window.Razorpay(options);
rzp.open();
setLoading(false);
};
return (
<button onClick={handlePayment} disabled={loading}>
{loading ? "Processing..." : `Pay ₹${amount}`}
</button>
);
}
This is the most important security step. Never trust the frontend response alone. Create app/api/razorpay/verify/route.ts:
import { NextResponse } from 'next/server';
import crypto from 'crypto';
export async function POST(req: Request) {
const { razorpay_order_id, razorpay_payment_id, razorpay_signature } = await req.json();
const body = `${razorpay_order_id}|${razorpay_payment_id}`;
const expected = crypto
.createHmac('sha256', process.env.RAZORPAY_KEY_SECRET!)
.update(body)
.digest('hex');
const ok = expected === razorpay_signature;
return NextResponse.json({ ok });
}
Webhooks let you catch payment events even if the user closes their browser mid-transaction. Set up a webhook URL in Razorpay Dashboard pointing to /api/razorpay/webhook, and verify the signature the same way as Step 6 using the webhook secret.
handler callbackOnce everything works in test mode:
A solid payment integration is often the difference between a shipped product and a stalled one. Razorpay's React and Next.js integration is one of the cleanest in the Indian fintech space, and following this checklist gives you a production-ready checkout in under a day. Tech Assistant has shipped 50+ Razorpay integrations for Indian clients. If you would rather hand this off to a team that does it every day, explore our website development service or talk to us.