Razorpay Payment Integration (MERN STACK)
Backend
Packages: Razorpay
Code:
const Razorpay = require('razorpay');
const dotenv = require("dotenv")
dotenv.config()
const razorpay = new Razorpay({
key_id: process.env.RAZ_KEY_ID,
key_secret: process.env.RAZ_KEY_SECRET,
});
exports.createOrder = async (req, res) => {
try {
const options = {
amount: req.body.amount,
currency: 'INR',
receipt: 'receipt_' + Math.random().toString(36).substring(7),
notes: req.body.notes
};
const order = await razorpay.orders.create(options);
res.status(200).json(order);
} catch (err) {
res.status(500).json({ error: err.message });
}
}
exports.verifyPayment = async (req, res) => {
try {
const { razorpay_order_id, razorpay_payment_id, razorpay_signature } = req.body;
const sign = razorpay_order_id + '|' + razorpay_payment_id;
const expectedSign = crypto.createHmac('sha256', process.env.RAZ_KEY_SECRET)
.update(sign.toString())
.digest('hex');
if (razorpay_signature === expectedSign) {
// Payment is verified
res.status(200).json({ message: 'Payment verified successfully' });
} else {
res.status(400).json({ error: 'Invalid payment signature' });
}
} catch (err) {
res.status(500).json({ error: err.message });
}
}
exports.getOrderDetails = async(req, res, next)=>{
try {
razorpay.orders.fetch(req.body.orderId).then(order => {
const notes = order; // Retrieve the product ID from the notes
res.status(200).json(notes)
// Proceed with the rest of the payment handling logic
});
} catch (error) {
next(error)
}
}
Frontend
packages: react-razorpay
Code:
import {useRazorpay} from "react-razorpay";
function PaymentButton() {
const [buyNowBtnClicked, setBuyNowBtnClicked] = useState(false);
const {Razorpay} = useRazorpay();
const currentVariant = useSelector(
(state) => state.activeProduct.currentVariant
);
const RAZORPAY_KEY_ID = import.meta.env.VITE_RAZ_ID;
const handlePayment = async () => {
try {
const response = await fetch(import.meta.env.VITE_BACKEND_HOST+"/order/create", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ amount: 5000 }),
});
const order = await response.json();
console.log(order)
const options = {
key: RAZORPAY_KEY_ID,
amount: order.amount,
currency: order.currency,
name: "NARA",
description: "Payment for your order",
order_id: order.id,
handler: async (response) => {
try {
console.log("OrderId Backend", order.id)
console.log("OrderId RazorPay",response.razorpay_order_id)
await fetch(import.meta.env.VITE_BACKEND_HOST+"/order/verify", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
razorpay_order_id: response.razorpay_order_id,
razorpay_payment_id: response.razorpay_payment_id,
razorpay_signature: response.razorpay_signature,
}),
});
// You have to check if the response is ok or not
before alerting the user that the payment was successful
alert("Payment successful!");
} catch (err) {
alert("Payment failed: " + err.message);
}
},
prefill: {
name: "John Doe",
email: "john@example.com",
contact: "+918210853664",
},
theme: {
color: "#080906",
},
};
const rzpay = new Razorpay(options);
rzpay.open(options);
} catch (err) {
alert("Error creating order: " + err.message);
}
};
return <button
disabled={!currentVariant}
className="relative mr-2 disabled:text-gray-200 px-4 py-2 border-2 shadow-lg xl:!shadow-none"
onClick={handlePayment}
>
{buyNowBtnClicked && (
<div className="absolute flex items-center justify-center top-0 right-0 left-0 bottom-0">
<Spinner />
</div>
)}
<span className={buyNowBtnClicked && "opacity-0"}>Buy Now</span>
</button>;
}
Comments
Post a Comment