Skip to content

Commit

Permalink
added razorpay payment for checkout
Browse files Browse the repository at this point in the history
  • Loading branch information
swatimoluguri committed May 9, 2024
1 parent 1850c2a commit 4577676
Show file tree
Hide file tree
Showing 10 changed files with 701 additions and 24 deletions.
5 changes: 3 additions & 2 deletions db.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ module.exports={
return cb(err);
})
},
getDb:()=>dbConnection
}
getDb:()=>dbConnection,
getOrderModel: () => dbConnection.collection('orders')
};
547 changes: 547 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"axios": "^1.6.8",
"cors": "^2.8.5",
"express": "^4.19.2",
"font-awesome": "^4.7.0",
"mongodb": "^6.5.0",
"mongoose": "^8.3.4",
"morgan": "^1.10.0",
"razorpay": "^2.9.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-redux": "^9.1.2",
Expand Down
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,5 @@
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
</html>
72 changes: 70 additions & 2 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
const express = require("express");
const cors = require("cors");
const morgan = require("morgan");
const { ObjectId } = require("mongodb");
const { connectToDb, getDb } = require("./db");
const { connectToDb, getDb, getOrderModel } = require("./db");
const app = express();
const Razorpay = require("razorpay");
const crypto = require("crypto");

app.use(express.urlencoded({ extended: true }));

const razorpay = new Razorpay({
key_id: "rzp_test_vorhZ7wKh3AFzX",
key_secret: "mk80OiNmNFnZIwmKYweWqdMj",
});

//middlewares
app.use(express.json());
let db;
app.use(cors());
app.use(morgan("dev"));

//connections
let db;
connectToDb((err) => {
if (!err) {
app.listen(3000, () => {
Expand All @@ -16,6 +32,8 @@ connectToDb((err) => {
}
});

//routes

app.get("/products", (req, res) => {
let products = [];
db.collection("products")
Expand Down Expand Up @@ -100,3 +118,53 @@ app.get("/products/:id", (req, res) => {
res.status(500).json({ error: "Could not fetch products" });
});
});

app.post("/checkout", async (req, res) => {
try {
const amount = req.body.val;
var options = {
amount: 100,
currency: "INR",
};
const order = await razorpay.orders.create(options);
const orderModel = getOrderModel();
await orderModel.insertOne({
order_id: order.id,
amount: amount,
});
res.json(order);
} catch (error) {
console.error("Error:", error);
res.status(500).json({ error: "Internal Server Error" });
}
});

app.post("/checkout/payment-verification", async (req, res) => {
const { razorpay_payment_id, razorpay_order_id, razorpay_signature } =
req.body;
const body_data = razorpay_order_id + "|" + razorpay_payment_id;
const response = crypto
.createHmac("sha256", "mk80OiNmNFnZIwmKYweWqdMj")
.update(body_data)
.digest("hex");
const isValid = response === razorpay_signature;
if (isValid) {
const orderModel = getOrderModel();
await orderModel.findOne(
{
order_id: razorpay_order_id,
},
{
$set: {
razorpay_payment_id: razorpay_payment_id,
razorpay_signature: razorpay_signature,
},
}
);
res.redirect(`/success?payment_id=${razorpay_payment_id}`
);
} else {
res.redirect("/failed");
}
return;
});
2 changes: 1 addition & 1 deletion src/App.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Routings from "./components/Routings";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { AppStore, persistor } from "./utils/AppStore"; // Import the updated AppStore and persistor
import { AppStore, persistor } from "./utils/AppStore";
import UserContext from "./utils/UserContext";
import { useState } from "react";
import Navbar from "./components/Navbar";
Expand Down
80 changes: 61 additions & 19 deletions src/components/Cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,27 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faTrash } from "@fortawesome/free-solid-svg-icons";
import DetailsStrip from "./DetailsStrip";
import EmptyCart from "../assets/empty-cart.jpg";
import axios from "axios";
import { useEffect, useState } from "react";

const Cart = () => {
const dispatch = useDispatch();
const [cartTotal, setCartTotal] = useState(0);
const [cartItems, setCartItems] = useState(0);
const cart = useSelector((store) => store.cart.items);
console.log(cart);
useEffect(() => {
let total = cart.reduce((acc, item) => {
acc += Math.round(item.price * 84) * item.count;
return acc;
}, 0);
let totalItems = cart.reduce((acc, item) => {
acc += item.count;
return acc;
}, 0);
setCartTotal(total);
setCartItems(totalItems);
}, [cart]);

function handleReduceCount(id) {
let item = {};
Expand All @@ -34,6 +50,36 @@ const Cart = () => {
function handleClearCart() {
dispatch(clearCart());
}

async function handleCheckout(val) {
const {data:{id}} = await axios.post("http://localhost:3000/checkout", {
val,
});

var options = {
"key": "rzp_test_vorhZ7wKh3AFzX", // Enter the Key ID generated from the Dashboard
"amount": "100", // Amount is in currency subunits. Default currency is INR. Hence, 50000 refers to 50000 paise
"currency": "INR",
"name": "Swati",
"description": "Test",
"image": "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQRY7zpT4pHNb8LZfnaP0xI7FYTkiZaYfPUhEaV1scVsQ&s",
"order_id":id, //This is a sample Order ID. Pass the `id` obtained in the response of Step 1
"callback_url": "http://localhost:3000/checkout/payment-verification",
"prefill": {
"name": "Gaurav Kumar",
"email": "[email protected]",
"contact": "9000090000"
},
"notes": {
"address": "Razorpay Corporate Office"
},
"theme": {
"color": "#3399cc"
}
};
var rzp1 = new window.Razorpay(options);
rzp1.open();
}
return (
<div>
<div className="flex flex-col items-center bg-[url('assets/bg.jpg')] bg-cover ">
Expand All @@ -59,13 +105,15 @@ const Cart = () => {
{cart.map((item, index) => (
<tr key={index} className="border-b border-gray-200">
<td className="p-3 flex items-center gap-6">
<div className="h-28 w-20 rounded-3xl">
<img
className="object-contain w-full h-full rounded-3xl"
src={item.image}
alt={item._id}
/>
</div>
<Link to={"/products/" + item._id} key={item._id}>
<div className="h-28 w-20 rounded-3xl">
<img
className="object-contain w-full h-full rounded-3xl"
src={item.image}
alt={item._id}
/>
</div>
</Link>
{item.title}
</td>
<td className="p-3 text-right">
Expand Down Expand Up @@ -129,12 +177,7 @@ const Cart = () => {
<table className="w-full">
<tr>
<th className="text-left p-2">Items</th>
<td className="text-right p-2">
{cart.reduce((acc, item) => {
acc += item.count;
return acc;
}, 0)}
</td>
<td className="text-right p-2">{cartItems}</td>
</tr>
<tr>
<th className="text-left p-2">Sub Total</th>
Expand All @@ -155,14 +198,13 @@ const Cart = () => {
<div className="flex justify-between p-4">
<div>Total</div>
<div>
{cart.reduce((acc, item) => {
acc += Math.round(item.price * 84) * item.count;
return acc;
}, 0)}
{cartTotal}
</div>
</div>
<div className="bg-app-green text-white w-fit px-4 py-2 text-lg font-semibold rounded-full mx-auto my-4">
<div
onClick={() => handleCheckout(cartTotal)}
className="cursor-pointer bg-app-green text-white w-fit px-4 py-2 text-lg font-semibold rounded-full mx-auto my-4"
>
Proceed to Checkout
</div>
</div>
Expand Down
6 changes: 6 additions & 0 deletions src/components/Failed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const Failed=()=>{
return(
<div>Failed</div>
)
}
export default Failed;
4 changes: 4 additions & 0 deletions src/components/Routings.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import Products from "./Products";
import ProductView from "./ProductView";
import Signup from "./Signup";
import Cart from "./Cart";
import Failed from "./Failed";
import Success from "./Success";

const Routings = () => {
return (
Expand All @@ -13,6 +15,8 @@ const Routings = () => {
<Route path="/products/:productId" element={<ProductView/>} />
<Route path="/signup" element={<Signup />} />
<Route path="/cart" element={<Cart />} />
<Route path="/success" element={<Success />} />
<Route path="/failed" element={<Failed />} />
</Routes>
);
};
Expand Down
4 changes: 4 additions & 0 deletions src/components/Success.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const Success=()=>{
return <div>Success</div>
}
export default Success;

0 comments on commit 4577676

Please sign in to comment.