<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kush Chaudhary</title>
    <description>The latest articles on DEV Community by Kush Chaudhary (@hanuchaudhary).</description>
    <link>https://dev.to/hanuchaudhary</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2313412%2F3dd3893c-d4ef-4cbb-beec-ab42ce3330cc.jpg</url>
      <title>DEV Community: Kush Chaudhary</title>
      <link>https://dev.to/hanuchaudhary</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hanuchaudhary"/>
    <language>en</language>
    <item>
      <title>How to Integrate RazorPay in Next.js 14/15 with Easy Steps.</title>
      <dc:creator>Kush Chaudhary</dc:creator>
      <pubDate>Sat, 25 Jan 2025 07:55:51 +0000</pubDate>
      <link>https://dev.to/hanuchaudhary/how-to-integrate-razorpay-in-nextjs-1415-with-easy-steps-fl7</link>
      <guid>https://dev.to/hanuchaudhary/how-to-integrate-razorpay-in-nextjs-1415-with-easy-steps-fl7</guid>
      <description>&lt;p&gt;Alright, let’s make this super simple! If you’re working on a Next.js project and need to integrate Razorpay for payments, just follow these steps, copy-paste the code, and you’re done. No fluff, just what you need&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Install Required Packages
&lt;/h2&gt;

&lt;p&gt;First, install the Razorpay Node.js SDK and other necessary packages. In your project directory, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install razorpay @types/razorpay axios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Get API Keys from Razorpay
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dashboard.razorpay.com/app/website-app-settings/api-keys" rel="noopener noreferrer"&gt;Get api keys from here&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvl8k48lcjvfjzeco62l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjvl8k48lcjvfjzeco62l.png" alt="Image description" width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Store your Razorpay keys in a &lt;code&gt;.env&lt;/code&gt; file at the root of your project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXT_PUBLIC_RAZORPAY_KEY_ID = YOUR_RAZORPAY_KEY_ID
RAZORPAY_KEY_ID = YOUR_RAZORPAY_KEY_ID
RAZORPAY_KEY_SECRET = YOUR_RAZORPAY_KEY_SECRET
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Create an Order API Route
&lt;/h2&gt;

&lt;p&gt;Next.js has a built-in API route system, making it easy to handle backend logic. Let’s create an API route for Razorpay to generate orders.&lt;/p&gt;

&lt;p&gt;Create a new API route &lt;code&gt;/api/createOrder/route.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextRequest, NextResponse } from "next/server";
import Razorpay from "razorpay";

const key_id = process.env.RAZORPAY_KEY_ID as string;
const key_secret = process.env.RAZORPAY_KEY_SECRET as string;

if (!key_id || !key_secret) {
    throw new Error("Razorpay keys are missing");
}

const razorpay = new Razorpay({
    key_id,
    key_secret
})

export type OrderBody = {
    amount: number;
    currency: string;
}

export async function POST(request: NextRequest) {
    try {

        const { amount, currency }: OrderBody = await request.json();
        if (!amount) {
            return NextResponse.json({ message: `Amount is required` }, { status: 400 })
        }

        const options = {
            amount,
            currency: currency || "INR",
            receipt: `receipt#${Date.now()}`,
        }

        const order = await razorpay.orders.create(options);
        console.log("Order Created Successfully");

        return NextResponse.json({ orderId: order.id }, { status: 200 })

    } catch (error) {
        return NextResponse.json({ message: "Server Error", error }, { status: 500 })
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Create a function for generating OrderId
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from "axios";

export async function createOrderId(amount: number, currency: string) {
    try {
        const response = await axios.post("/api/createOrder", {
            amount: amount * 100, // Convert to paise
            currency: "INR",
        });

        console.log("Order Response:", response.data);
        return response.data.orderId;
    } catch (error) {
        console.error(error);
        throw new Error("Failed to create order");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Create a Checkout Button
&lt;/h2&gt;

&lt;p&gt;Create a reusable component &lt;code&gt;/components/BuyButton.tsx&lt;/code&gt; for the Razorpay checkout button. Copy the below code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client";

import axios from "axios";
import React from "react";
import Script from "next/script";
import { createOrderId } from "@/utils/createOrderId";

export default function PurchaseButton() {
  const [isLoading, setIsLoading] = React.useState(false);

  const handlePayment = async () =&amp;gt; {
    setIsLoading(true);
    const price = 100; // Replace with dynamic price
    try {
      const orderId: string = await createOrderId(price, "INR");
      const options = {
        key: process.env.NEXT_PUBLIC_RAZORPAY_KEY_ID,
        amount: price * 100,
        currency: "INR",
        name: "YOUR_COMPANY_NAME", // Replace with dynamic company name
        description: "Payment for your order", // Replace with dynamic order description
        order_id: orderId,
        handler: async function (response: any) {
          try {
            const paymentResponse = await axios.post("/api/verifyOrder", {
              razorpay_order_id: orderId,
              razorpay_payment_id: response.razorpay_payment_id,
              razorpay_signature: response.razorpay_signature,
            });

            alert("Payment Successful!");
            console.log(paymentResponse.data);
          } catch (error) {
            alert("Payment verification failed. Please contact support.");
            console.error(error);
          }
        },
        prefill: {
          name: "YOUR_NAME", // Replace with dynamic user data
          email: "YOUR_EMAIL", // Replace with dynamic user data
        },
        theme: {
          color: "#3399cc",
        },
      };

      const razorpay = new (window as any).Razorpay(options);
      razorpay.on("payment.failed", function (response: any) {
        alert("Payment failed");
        console.error(response.error);
      });
      razorpay.open();
    } catch (error) {
      alert("Payment failed. Please try again.");
      console.error(error);
    } finally {
      setIsLoading(false);
    }
  };

  return (
    &amp;lt;&amp;gt;
      &amp;lt;button
        className="bg-emerald-700 text-white font-semibold px-4 py-2 rounded-xl hover:bg-emerald-600 transition-all duration-300 hover:shadow-lg hover:scale-105"
        onClick={handlePayment}
        disabled={isLoading}
      &amp;gt;
        {isLoading ? "Processing..." : "Buy Now"}
      &amp;lt;/button&amp;gt;
      &amp;lt;Script
        id="razorpay-checkout-js"
        src="https://checkout.razorpay.com/v1/checkout.js"
      /&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 8: Verify Payment
&lt;/h2&gt;

&lt;p&gt;For added security, you can verify the payment signature server-side. Create a new API route &lt;code&gt;/api/verifyOrder/route.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextRequest, NextResponse } from "next/server";
import crypto from "crypto";

export interface VerifyBody {
    razorpay_order_id: string;
    razorpay_payment_id: string;
    razorpay_signature: string
};

export async function POST(request: NextRequest) {
    try {
        const { razorpay_order_id, razorpay_payment_id, razorpay_signature }: VerifyBody = await request.json();

        if (!razorpay_order_id || !razorpay_payment_id || !razorpay_signature) {
            return NextResponse.json({ error: "Missing required parameters", success: false }, { status: 400 })
        }

        const secret = process.env.RAZORPAY_KEY_SECRET as string
        if (!secret) { return NextResponse.json({ error: "Razorpay secret not found" }, { status: 400 }) }

        const HMAC = crypto.createHmac("sha256", secret)
        HMAC.update(`${razorpay_order_id}|${razorpay_payment_id}`)
        const generatedSignature = HMAC.digest("hex")

        if (generatedSignature === razorpay_signature) {
            return NextResponse.json({ message: "Payment verified successfully", success: true })
        } else {
            return NextResponse.json({ error: "Invalid signature", success: false }, { status: 400 })
        }
    } catch (error) {
        return NextResponse.json({ error: "An error occurred", success: false }, { status: 500 })
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is how you might create a products page and add checkout flow:&lt;br&gt;
checkout this Github repository where I have created complete payment flow on a products page: &lt;a href="https://github.com/hanuchaudhary/RazorpayIntegration" rel="noopener noreferrer"&gt;github/hanuchaudhary/RazorpayIntegration&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Done!
&lt;/h2&gt;

&lt;p&gt;That’s it! You’ve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installed the required dependencies.&lt;/li&gt;
&lt;li&gt;Added Razorpay keys to &lt;code&gt;.env&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Created two POST API routes: &lt;code&gt;/api/createOrder/route.ts&lt;/code&gt; and &lt;code&gt;/api/verifyOrder/route.ts&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Built a reusable button component.&lt;/li&gt;
&lt;li&gt;Added the Razorpay script.
For extra features like webhooks or subscriptions, check out the &lt;a href="https://razorpay.com/docs/#home-payments" rel="noopener noreferrer"&gt;Razorpay Documentation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Integrating Razorpay with Next.js 14/15 is straightforward and efficient. By following these steps, you can securely accept payments in your application. For advanced features like subscriptions or webhooks, refer to the Razorpay Documentation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading this blog! Don’t forget to leave a comment💬!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>razorpay</category>
      <category>nextjs</category>
      <category>payment</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
