title: Unable to set up razorpay payment gateway
body: <p>I have built a checkout page where on clicking the pay button a payment page should render. But due to some issue I can't find why?</p>
  <p>The checkout page:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"&gt;&lt;/script&gt;
  import Link from 'next/link'
  import React, { useState, useEffect } from 'react'
  import Head from 'next/head'
  import Script from 'next/script'
  import { AiFillMinusCircle, AiFillPlusCircle } from 'react-icons/ai'
  import { BsFillBagCheckFill } from 'react-icons/bs'
  import { ToastContainer, toast } from 'react-toastify'
  import 'react-toastify/dist/ReactToastify.css';
  
  const Checkout = ({ cart, clearCart, subTotal, addToCart, removeFromCart }) =&gt; {
  
    const [name, setName] = useState('')
    const [email, setEmail] = useState('')
    const [address, setAddress] = useState('')
    const [phone, setPhone] = useState('')
    const [pincode, setPincode] = useState('')
    const [city, setCity] = useState('')
    const [state, setState] = useState('')
    const [disabled, setDisabled] = useState(true)
    const [user, setUser] = useState({ value: null })
  
    useEffect(() =&gt; {
      const myuser = JSON.parse(localStorage.getItem('myuser'));
      if (myuser &amp;&amp; myuser.token) {
        setUser(myuser)
        setEmail(myuser.email)
        fetchData(myuser.token)
      }
    }, [])
  
    useEffect(() =&gt; {
      if (name.length &gt; 3 &amp;&amp; email.length &gt; 3 &amp;&amp; address.length &gt; 3 &amp;&amp; phone.length &gt; 3 &amp;&amp; pincode.length &gt; 3) {
        setDisabled(false)
      }
      else {
        setDisabled(true)
      }
    }, [name, email, address, phone, pincode])
  
    const fetchData = async (token) =&gt; {
      let data = { token: token }
      let a = await fetch(`${process.env.NEXT_PUBLIC_HOST}/api/getuser`, {
        method: 'POST', // or 'PUT'
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      })
      let res = await a.json()
      setName(res.name)
      setAddress(res.address)
      setPincode(res.pincode)
      setPhone(res.phone)
      getPinCode(res.pincode)
    }
  
    const getPinCode = async (pincode) =&gt; {
      let url = 'https://api.postalpincode.in/pincode/' + pincode
      let pins = await fetch(url, {
        Method: 'GET'
      })
      let pinJson = await pins.json()
      if (pinJson[0].Status == 'Success') {
        setState(pinJson[0].PostOffice[0].State)
        setCity(pinJson[0].PostOffice[0].District)
      }
      else {
        setState('')
        setCity('')
      }
    }
  
  
  
    const handleChange = async (e) =&gt; {
  
      if (e.target.name == 'name') {
        setName(e.target.value)
      }
      else if (e.target.name == 'email') {
        setEmail(e.target.value)
      }
      else if (e.target.name == 'address') {
        setAddress(e.target.value)
      }
      else if (e.target.name == 'phone') {
        setPhone(e.target.value)
      }
      else if (e.target.name == 'pincode') {
        setPincode(e.target.value)
        if (e.target.value.length == 6) {
          getPinCode(e.target.value)
        }
      }
    }
  
    const initializeRazorpay = () =&gt; {
      return new Promise((resolve) =&gt; {
        const script = document.createElement("script");
        script.src = "https://checkout.razorpay.com/v1/checkout.js";
        console.log("intialzeRazorpay")
  
        script.onload = () =&gt; {
          resolve(true);
        };
        script.onerror = () =&gt; {
          resolve(false);
        };
  
        document.body.appendChild(script);
      });
    };
  
    const makePayment = async () =&gt; {
      const res = await initializeRazorpay();
      let oid = Math.floor(Math.random() * Date.now());
      if (!res) {
        alert("Your are offline.... Razorpay SDK Failed to load");
        return;
      }
  
      const pdata = { cart, subTotal: subTotal, oid, email: email, name, address, pincode, phone, state, city };
        let data = await fetch(`${process.env.NEXT_PUBLIC_HOST}/api/pretransaction`, {
          method: 'POST', // or 'PUT'
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(pdata),
        })
  
      if (!data.success) {
        toast.error(data.err, {
          position: "top-center",
          autoClose: 3000,
          hideProgressBar: false,
          closeOnClick: true,
          pauseOnHover: true,
          draggable: true,
          progress: undefined,
        });
      }
      else {
          var options = {
          key: process.env.RAZORPAY_KEY, // Enter the Key ID generated from the Dashboard
          name: "Pixelwear",
          currency: "INR",
          amount: data.amount,
          order_id: data.id,
          description: "Thank You for your test donation",
          image: "/logo.png",
          handler: function (response) {
            // 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: name,
            email: email,
            contact: phone,
          },
        };
  
        const paymentObject = new window.Razorpay(options);
        paymentObject.open();
      }
    };
  
    return (
      &lt;&gt;
        &lt;div className='container px-2 sm:m-auto'&gt;
          &lt;ToastContainer
            position="top-center"
            autoClose={5000}
            hideProgressBar={false}
            newestOnTop={false}
            closeOnClick
            rtl={false}
            pauseOnFocusLoss
            draggable
            pauseOnHover
          /&gt;
          &lt;Head&gt;&lt;meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0" /&gt;&lt;/Head&gt;
          &lt;h1 className='font-bold text-3xl my-8 text-center'&gt;Checkout&lt;/h1&gt;
          &lt;h2 className='font-semibold text-xl'&gt;1. Delivery Details&lt;/h2&gt;
          &lt;div className="mx-auto flex my-2"&gt;
            &lt;div className="px-2 w-1/2"&gt;
              &lt;div className="mb-4"&gt;
                &lt;label htmlFor="name" className="leading-7 text-sm text-gray-600"&gt;Name&lt;/label&gt;
                &lt;input value={name} onChange={handleChange} type="text" id="name" name="name" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" /&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div className="px-2 w-1/2"&gt;
              &lt;div className="mb-4"&gt;
                &lt;label htmlFor="email" className="leading-7 text-sm text-gray-600"&gt;Email&lt;/label&gt;
                {user &amp;&amp; user.token ? &lt;input value={user.email} type="email" id="email" name="email" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" readOnly /&gt; : &lt;input value={email} onChange={handleChange} type="email" id="email" name="email" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" /&gt;}
  
              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;
          &lt;div className="px-2 w-full"&gt;
            &lt;div className="mb-4"&gt;
              &lt;label htmlFor="address" className="leading-7 text-sm text-gray-600"&gt;Address&lt;/label&gt;
              &lt;textarea onChange={handleChange} value={address} name="address" id="address" cols="30" rows="2" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"&gt;&lt;/textarea&gt;
            &lt;/div&gt;
          &lt;/div&gt;
          &lt;div className="mx-auto flex my-2"&gt;
            &lt;div className="px-2 w-1/2"&gt;
              &lt;div className="mb-4"&gt;
                &lt;label htmlFor="phone" className="leading-7 text-sm text-gray-600"&gt;Phone&lt;/label&gt;
                &lt;input value={phone} onChange={handleChange} placeholder="Your 10 digit phone number" type="phone" id="phone" name="phone" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" /&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div className="px-2 w-1/2"&gt;
              &lt;div className="mb-4"&gt;
                &lt;label htmlFor="pincode" className="leading-7 text-sm text-gray-600"&gt;Pincode&lt;/label&gt;
                &lt;input value={pincode} onChange={handleChange} type="text" id="pincode" name="pincode" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" /&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;
          &lt;div className="mx-auto flex my-2"&gt;
            &lt;div className="px-2 w-1/2"&gt;
              &lt;div className="mb-4"&gt;
                &lt;label htmlFor="state" className="leading-7 text-sm text-gray-600"&gt;State&lt;/label&gt;
                &lt;input onChange={handleChange} value={state} type="text" id="state" name="state" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" /&gt;
              &lt;/div&gt;
            &lt;/div&gt;
            &lt;div className="px-2 w-1/2"&gt;
              &lt;div className="mb-4"&gt;
                &lt;label htmlFor="city" className="leading-7 text-sm text-gray-600"&gt;District&lt;/label&gt;
                &lt;input onChange={handleChange} value={city} type="text" id="city" name="city" className="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" /&gt;
              &lt;/div&gt;
            &lt;/div&gt;
          &lt;/div&gt;
          &lt;h2 className='font-semibold text-xl'&gt;2. Review Cart Items &amp; Pay&lt;/h2&gt;
          &lt;div className="sideCart bg-blue-100 p-6 m-2"&gt;
  
            &lt;ol className='list-decimal font-semibold'&gt;
              {Object.keys(cart).length == 0 &amp;&amp; &lt;div className='my-4 font-semibold'&gt;Your cart is Empty!&lt;/div&gt;}
              {Object.keys(cart).map((k) =&gt; {
                return &lt;li key={k}&gt;
                  &lt;div className="item flex my-5"&gt;
                    &lt;div className='font-semibold'&gt;{cart[k].name} ({cart[k].size}/{cart[k].variant})&lt;/div&gt;
                    &lt;div className='flex items-center justify-center w-1/3 font-semibold text-lg'&gt;
                      &lt;AiFillMinusCircle onClick={() =&gt; { removeFromCart(k, 1, cart[k].price, cart[k].name, cart[k].size, cart[k].variant, cart[k].category, cart[k].img) }} className='cursor-pointer text-blue-500' /&gt;&lt;span className='mx-2 text-sm' &gt;{cart[k].qty}&lt;/span&gt;
                      &lt;AiFillPlusCircle onClick={() =&gt; { addToCart(k, 1, cart[k].price, cart[k].name, cart[k].size, cart[k].variant, cart[k].category, cart[k].img) }} className='cursor-pointer text-blue-500' /&gt;&lt;/div&gt;
                  &lt;/div&gt;
                &lt;/li&gt;
              })}
            &lt;/ol&gt;
            &lt;span className="font-bold"&gt;Subtotal: ₹{subTotal}&lt;/span&gt;
          &lt;/div&gt;
          &lt;div className="mx-4"&gt;
            &lt;Link href={'/checkout'} &gt;&lt;button disabled={disabled} onClick={makePayment} className="disabled:bg-indigo-300 flex mr-2 text-white bg-indigo-500 border-0 py-2 px-2 focus:outline-none hover:bg-indigo-600 rounded text-sm"&gt;&lt;BsFillBagCheckFill className='m-1' /&gt;Pay ₹{subTotal}&lt;/button&gt;&lt;/Link&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/&gt;
    )
  }
  
  export default Checkout</code></pre>
  </div>
  </div>
  </p>
  <p>pretransaction page:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"&gt;&lt;/script&gt;
  import Order from "../../models/Order"
  import Product from "../../models/Product"
  import connectDb from "../../middleware/mongoose"
  require('dotenv').config()
  const Razorpay = require("razorpay");
  const shortid = require("shortid");
  
  const handler = async (req, res) =&gt; {
      if (req.method == 'POST') {
  
          //Check if the pincode is serviceable
          let url = 'https://api.postalpincode.in/pincode/' + req.body.pincode
          let pins = await fetch(url, {
              Method: 'GET'
          })
          let pinJson = await pins.json()
          if (pinJson[0].Status != 'Success') {
              res.status(200).json({ success: false, "error": "The pincode you have entered is not serviceable.", cartClear: false })
              return
          }
          //Check if the cart is tampered
          let product, sumTotal = 0;
          let cart = req.body.cart;
          if (req.body.subTotal &lt;= 0) {
              res.status(200).json({ success: false, "error": "Your Cart is empty. Please build your cart and try again!", cartClear: false })
              return
          }
  
          for (let item in cart) {
              product = await Product.findOne({ slug: item })
              sumTotal += cart[item].price * cart[item].qty
  
              //Check if the cart items are out of stock
              if (product.availableQty &lt; cart[item].qty) {
                  res.status(200).json({ success: false, "error": "Some items in your cart are out of stock.", cartClear: true })
                  return
              }
              if (product.price != cart[item].price) {
                  res.status(200).json({ success: false, "error": "price of some items in cart have changed", cartClear: true })
                  return
              }
          }
          if (sumTotal != req.body.subTotal) {
              res.status(200).json({ success: false, "error": "price of some items in cart have changed", cartClear: true })
              return
          }
  
          //Check if the details are valid
          if (req.body.phone.length !== 10 || !Number.isInteger(Number(req.body.phone))) {
              res.status(200).json({ success: false, "error": "Please enter your 10 digit phone number", cartClear: false })
              return
          }
          if (req.body.pincode.length !== 6 || !Number.isInteger(Number(req.body.pincode))) {
              res.status(200).json({ success: false, "error": "Please enter your 6 digit pincode", cartClear: false })
              return
          }
          
          const razorpay = new Razorpay({
              key_id: process.env.RAZORPAY_KEY,
              key_secret: process.env.RAZORPAY_SECRET,
          });
  
          const payment_capture = 1;
          const amount = req.body.subTotal;
          const currency = "INR";
          const options = {
              amount: (amount * 100).toString(),
              currency,
              receipt: shortid.generate(),
              payment_capture,
          };
  
          try {
              const response = await razorpay.orders.create(options);
              // Initiate an order corresponding to the order id
          let order = new Order({
              email: req.body.email,
              name: req.body.name,
              phone: req.body.phone,
              orderId: response.id,
              address: req.body.address,
              district: req.body.city,
              state: req.body.state,
              pincode: req.body.pincode,
              amount: req.body.subTotal,
              products: req.body.cart,
          })
          await order.save()
              res.status(200).json({
                  success: true,
                  id: response.id,
                  currency: response.currency,
                  amount: response.amount,
              });
              return
          } catch (err) {
              console.log(err);
              res.status(400).json({ success: false , err: err});
              return
          }
          
      }
  }
  
  export default connectDb(handler);</code></pre>
  </div>
  </div>
  </p>
  <p>Everything is working fine, but when I click on the pay button the razorpay page is not rendering.
  And in the console it is showing one error, Invalid HMR message: {&quot;event&quot;:&quot;serverOnlyChanges&quot;,&quot;pages&quot;:[&quot;/api/pretransaction&quot;]}.
  <a href="https://i.stack.imgur.com/PBQKT.png" rel="nofollow noreferrer">Console Image</a></p>
  <p>How to fix this error?</p>