Skip to content

Commit

Permalink
add payment gateway with validation
Browse files Browse the repository at this point in the history
  • Loading branch information
IAMAmanRaj committed Apr 25, 2024
1 parent b164de7 commit b34d404
Show file tree
Hide file tree
Showing 10 changed files with 2,217 additions and 32 deletions.
6 changes: 6 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
MONGO="mongodb+srv://imamanraj87:admin@cluster0.ighc56x.mongodb.net/Payments_Razorpay?retryWrites=true&w=majority"
JWT_SECRET="jwtsecret"
RAZORPAY_KEY_ID="rzp_test_KS6dMRpZmkqBpQ"
RAZORPAY_SECRET="yr0aO0XN2CzkdkW3aG8aGdeS"

PORT=5000
1 change: 1 addition & 0 deletions app/.gitignore → .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ dist-ssr
*.njsproj
*.sln
*.sw?
.env
1 change: 0 additions & 1 deletion README.md

This file was deleted.

101 changes: 101 additions & 0 deletions api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import express from "express";

import mongoose from "mongoose";

import dotenv from "dotenv";

import cookieParser from "cookie-parser";

import path from "path";

import Razorpay from "razorpay";

import crypto from "crypto";

import cors from "cors";

dotenv.config();

const __dirname = path.resolve();
mongoose
.connect(process.env.MONGO)
.then(() => {
console.log("Connected to MongoDB");
})
.catch((err) => {
console.log(err);
});

const app = express();

app.use(express.json());

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

app.use(cookieParser());

app.use(cors());

app.post("/api/payment", async (req, res) => {
try {
const razorpay = new Razorpay({
key_id: process.env.RAZORPAY_KEY_ID,
key_secret: process.env.RAZORPAY_SECRET,
});

if (!req.body) {
return res.status(400).send("Bad request");
}
const options = req.body;

const order = await razorpay.orders.create(options);

if (!order) {
return res.status(400).send("Bad request");
}

res.json(order);
} catch (error) {
console.log(error);
res.status(500).send(error);
}
});

app.post("/api/validate", async (req, res) => {
const { razorpay_order_id, razorpay_payment_id, razorpay_signature } =
req.body;
const sha = crypto.createHmac("sha256", process.env.RAZORPAY_SECRET);

sha.update(`${razorpay_order_id}|${razorpay_payment_id}`);
const digest = sha.digest("hex");

if (digest !== razorpay_signature) {
return res.status(400).json({ msg: "Transaction is not legit!" });
}
res.json({
msg: " Transaction is legit !",
orderId: razorpay_order_id,
paymentId: razorpay_payment_id,
});
});

app.listen(3000, () => {
console.log("Server is listening on port 3000");
});

app.use((err, req, res, next) => {
//middleware for handling errors
const statusCode = err.statusCode || 500;
const message = err.message || "Internal Server Error";
return res.status(statusCode).json({
success: false,
message,
statusCode,
});
});

app.use(express.static(path.join(__dirname, "/client/dist")));

app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "client", "dist", "index.html"));
});
12 changes: 8 additions & 4 deletions app/index.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Space+Grotesk&display=swap"
rel="stylesheet"
/>
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>portfolio</title>
</head>
Expand Down
Binary file added app/public/images/razorpay-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
128 changes: 104 additions & 24 deletions app/src/components/ui/Footer.jsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,111 @@
import React from 'react'
import React from "react";
import { BsGithub } from "react-icons/bs";
import { FaLinkedinIn } from "react-icons/fa";
import { FaInstagram } from "react-icons/fa6";
import { Link } from 'react-router-dom';
import { Link, json } from "react-router-dom";
import logo from "../../../public/images/razorpay-icon.png";
const Footer = () => {
const paymentHandler = async (event) => {
const amount = 10000;
const currency = "INR";
const receiptId = "12345678";

const response = await fetch("http://localhost:3000/api/payment", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
amount,
currency,
receipt: receiptId,
}),
});

const order = await response.json();

var option = {
key: "",
amount,
currency,
name: "Portfolio | Aman Raj",
description: "Test Transaction",
image: { logo },
order_id: order.id,
handler: async function (response) {
const body = { ...response };
const validateResponse = await fetch(
"http://localhost:3000/api/validatePayment",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(body),
}
);
const jsonResponse = await validateResponse.json();
console.log(jsonResponse);
},
prefill: {
name: "Aman Raj",
email: "imamanraj87@gmail.com",
contact: "7061410096",
},
notes: {
address: "Razorpay Corporate Office",
},
theme: {
color: "#3399cc",
},
};
var rzp1 = new Razorpay(option);
rzp1.on("payment.failed", function (response) {
alert(response);
});

rzp1.open();
event.preventDefault();
};

return (
<footer className="footer pt-16 sm:pt-8 relative z-[20] border-white footer-center p-10 text-base-content rounded">
<nav className="grid grid-flow-col gap-4">
<a className="link link-hover">About Me</a>
<a className="link link-hover">Contact</a>
<a className="link link-hover">My Resume</a>

</nav>
<nav>
<div className="grid grid-flow-col gap-4">
<Link to="https://www.linkedin.com/in/aman-raj-a3710622a/"><FaLinkedinIn className='hover:text-blue-600 transition-all duration-800' size={30}/></Link>
<Link to="https://github.com/IAMAmanRaj"><BsGithub className='hover:opacity-85 transition-all duration-800 ' size={30}/></Link>
<Link to="https://www.instagram.com/i_m_amanraj87/"><FaInstagram className='hover:text-red-900 transition-all duration-800' size={30}/></Link>
</div>
</nav>
<aside>
<p>Copyright © 2024 - All right reserved</p>
<p>{`Made with <3 `}</p>
<p>{`Feel free to react out to me `}</p>
</aside>
</footer>
)
}
<nav className="grid grid-flow-col gap-4">
<a onClick={paymentHandler} className="link link-hover">
Support Me
</a>
<a className="link link-hover">Contact</a>
<a className="link link-hover">My Resume</a>
</nav>
<nav>
<div className="grid grid-flow-col gap-4">
<Link to="https://www.linkedin.com/in/aman-raj-a3710622a/">
<FaLinkedinIn
className="hover:text-blue-600 transition-all duration-800"
size={30}
/>
</Link>
<Link to="https://github.com/IAMAmanRaj">
<BsGithub
className="hover:opacity-85 transition-all duration-800 "
size={30}
/>
</Link>
<Link to="https://www.instagram.com/i_m_amanraj87/">
<FaInstagram
className="hover:text-red-900 transition-all duration-800"
size={30}
/>
</Link>
</div>
</nav>
<aside>
<p>Copyright © 2024 - All right reserved</p>
<p>{`Made with <3 `}</p>
<p>{`Feel free to reach out :) `}</p>
</aside>
</footer>
);
};

export default Footer
export default Footer;
6 changes: 3 additions & 3 deletions app/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
})
});
Loading

0 comments on commit b34d404

Please sign in to comment.