How To Integrate Phonepe Payment Gateway In Website With React/Next Js. Latest Version

  • Posted on December 16, 2023
  • Technology
  • By MmantraTech
  • 1218 Views

Introduction to Next.js and PhonePe Integration

 

In this tutorial, you'll receive a detailed, step-by-step explanation of how to seamlessly integrate the PhonePe payment gateway into a website using React.js or Next.js.

The content of this video is derived from the most recent official PhonePe documentation available on their website. It covers essential insights into both Sandbox and Live integrations.


Video Tutorial : https://www.youtube.com/watch?v=4oDmBjusoKM


As we know, Next.js has become the go-to framework for building React applications. Pairing this robust framework with a reliable payment gateway like PhonePe can elevate the user experience to new heights. Let's begin the seamless integration of PhonePe with Next.js, exploring step-by-step guidance for developers.

Understanding Next.js Framework

Next.js, built on top of React, brings a set of powerful features to the table. From server-side rendering to automatic code splitting, Next.js is designed to enhance the performance and SEO-friendliness of web applications. Its ability to create dynamic, modern websites makes it a popular choice among developers.

Introduction to PhonePe Payment Gateway

PhonePe, a leading digital payment platform in India, offers a comprehensive set of features for businesses looking to integrate secure and efficient payment options. With a user-friendly interface and support for various payment methods, PhonePe becomes an ideal choice for Next.js projects aiming to provide a smooth checkout experience.

Prerequisites for Integration

Before diving into the integration process, ensure you have a Next.js project set up. Additionally, register for a PhonePe merchant account to obtain the necessary API credentials, including API keys and merchant IDs. However, I am also going to explain Sandbox integration so that you can understand the basic idea of PhonePe integration.

 

 

 

Installation and Configuration

Step 1:

npx create-next-app@latest

Step 2:

Step 3:

Please create files and folders, as you can see in the above screenshot. My code will follow the above architecture, which is based on the latest NextJS 14. However, you can only remove logic from your code.

Step 4:

Copy and paste the below code into the app/page.js

import Image from "next/image";
import Pay from "./components/Pay";

//for tutorials : https://mmantratech.com/
//for channel : https://www.youtube.com/channel/UC9HIIz8gI5oOK92BctimlRw
//contact : techmalasi@gmail.com
//For products :https://mdeals.mmantratech.com/blog/best-sellers-laptop-you-can-not-miss-them/

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

Step 5:

Copy and paste the below code into the app/components/Pay.jsx

"use client"
import React, { useState } from 'react'
import { useRouter } from "next/navigation";
import sha256 from "crypto-js/sha256";
import { redirect } from "next/navigation";
import axios from "axios";
import { v4 as uuidv4 } from 'uuid';


const Pay = () => {

    const router = useRouter();

    const  [data,setData] =useState();

  const handleFormData = (e) => {
    // console.log(e.target.value);
    const dd = { ...data, [e.target.name]: e.target.value };
    setData(dd);
  };


  const makePayment=async(e)=>{

    e.preventDefault();

    const transactionid = "Tr-"+uuidv4().toString(36).slice(-6);

    const payload = {
        merchantId: process.env.NEXT_PUBLIC_MERCHANT_ID,
        merchantTransactionId: transactionid,
        merchantUserId: 'MUID-'+uuidv4().toString(36).slice(-6),
        amount: 10000,
        redirectUrl: `http://localhost:3000/api/status/${transactionid}`,
        redirectMode: "POST",
        callbackUrl: `http://localhost:3000/api/status/${transactionid}`,
        mobileNumber: '9999999999',
        paymentInstrument: {
          type: "PAY_PAGE",
        },
      };


      const dataPayload = JSON.stringify(payload);
      console.log(dataPayload);

      const dataBase64 = Buffer.from(dataPayload).toString("base64");
      console.log(dataBase64);


  const fullURL =
        dataBase64 + "/pg/v1/pay" + process.env.NEXT_PUBLIC_SALT_KEY;
     const dataSha256 = sha256(fullURL);

      const checksum = dataSha256 + "###" + process.env.NEXT_PUBLIC_SALT_INDEX;
      console.log("c====",checksum);



    const UAT_PAY_API_URL =
    "https://api-preprod.phonepe.com/apis/pg-sandbox/pg/v1/pay";


  const response = await axios.post(
    UAT_PAY_API_URL,
    {
      request: dataBase64,
    },
    {
      headers: {
        accept: "application/json",
        "Content-Type": "application/json",
         "X-VERIFY": checksum,
      },
    }
  );


  const redirect=response.data.data.instrumentResponse.redirectInfo.url;
  router.push(redirect)


  }


  return (
       <div className="flex min-h-full flex-col justify-center px-6 py-12 lg:px-8">
    <div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
      <form className="space-y-6" action="#" method="POST">
        <div>
          <label
            htmlFor="name"
            className="block text-sm font-medium leading-6 text-gray-900"
          >
            Name
          </label>
          <div className="mt-2">
            <input
              id="name"
              name="name"
              value="DemoTest"
              onChange={(e) => handleFormData(e)}
              type="name"
              autoComplete="name"
              required=""
              className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
            />
          </div>
        </div>
        <div>
          <label
            htmlFor="Mobile"
            className="block text-sm font-medium leading-6 text-gray-900"
          >
            Mobile
          </label>
          <div className="mt-2">
            <input
              id="Mobile"
              name="mobile"
              value="999999999"
              onChange={(e) => handleFormData(e)}
              autoComplete="Mobile"
              required=""
              className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
            />
          </div>
        </div>
        <div>
          <label
            htmlFor="Amount"
            className="block text-sm font-medium leading-6 text-gray-900"
          >
            Amount
          </label>
          <div className="mt-2">
            <input
              id="Amount"
              name="amount"
              value="10"
              autoComplete="Amount"
              onChange={(e) => handleFormData(e)}
              required=""
              className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
            />
          </div>
        </div>
        <div>
          <label
            htmlFor="MUID"
            className="block text-sm font-medium leading-6 text-gray-900"
          >
            MUID
          </label>
          <div className="mt-2">
            <input
              id="MUID"
              name="muid"
              value="nuid-909090"
              onChange={(e) => handleFormData(e)}
              autoComplete="MUID"
              required=""
              className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
            />
          </div>
        </div>
        <div></div>
        <div>
          <button
            onClick={(e) => makePayment(e)}
            className="flex w-full justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm font-semibold leading-6 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
          >
            Pay
          </button>
        </div>
      </form>
    </div>
  </div>
  )
}

export default Pay

Step 6:

Copy and paste the below code into the app/api/status/[id]/route.jsx

import { NextResponse } from "next/server";
import sha256 from "crypto-js/sha256";
import axios from "axios";

export async function POST(req, res) {
  const data = await req.formData();
  console.log(data);
  const status = data.get("code");
  const merchantId = data.get("merchantId");
  const transactionId = data.get("transactionId");

  const st =
    `/pg/v1/status/${merchantId}/${transactionId}` +
    process.env.NEXT_PUBLIC_SALT_KEY;
  // console.log(st)
  const dataSha256 = sha256(st);

  const checksum = dataSha256 + "###" + process.env.NEXT_PUBLIC_SALT_INDEX;
  console.log(checksum);




  const options = {
    method: "GET",
    url: `https://api-preprod.phonepe.com/apis/pg-sandbox/pg/v1/status/${merchantId}/${transactionId}`,
    headers: {
      accept: "application/json",
      "Content-Type": "application/json",
      "X-VERIFY": checksum,
      "X-MERCHANT-ID": `${merchantId}`,
    },
  };

  // CHECK PAYMENT STATUS
  const response = await axios.request(options);
  console.log("r===", response.data.code);


  if (response.data.code == "PAYMENT_SUCCESS")
  return NextResponse.redirect("http://localhost:3000/success",{
    status: 301,
  });
else return NextResponse.redirect("http://localhost:3000/failure",{
  // a 301 status is required to redirect from a POST to a GET route
  status: 301,
});


}

Step 7:

Copy and paste the below code into the app/success/page.jsx

import React from 'react'

const page = () => {
  return (
    <div className='flex justify-center items-center text-center'>
    You payment has been done successfully
    </div>
  )
}

export default page

 

Video Tutorial : https://www.youtube.com/watch?v=4oDmBjusoKM

Key questions addressed in this tutorial are:

Github link : https://github.com/TechMalasi/updated-PhonePe-Integration-with-React-Next-JS

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

 

for best laptops: https://mdeals.mmantratech.com/blog/best-sellers-laptop-you-can-not-miss-them/

Hostinger Hosting Plan: https://hostinger.in?REFERRALCODE=1BRIJESH70

 

In conclusion, integrating PhonePe with Next.js offers a powerful solution for developers seeking a seamless payment gateway for their web applications. By following the outlined steps and best practices, you can ensure a secure, efficient, and user-friendly payment experience.

 

#PhonePeTutorial,
#ReactPaymentGateway,
#NextJSPhonePeIntegration,
#PhonePeAPIGuide,
#SandboxIntegration,
#LivePaymentIntegration,
#ReactPhonePePayment,
#NextJSv31Integration,
#HighVolumePayments,
#LatestDocumentation,
#BestPractices,
#ReactDevelopmentGuide,
#NextJSTips,
#WebDevTutorials,
#PaymentGatewaySolutions,
#StepByStepIntegration,
#DeveloperResources,
#OnlinePaymentTutorial,
#TechHowTo,
#WebDevInsights,

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