diff --git a/backend/api/controllers/PaymentGetway.js b/backend/api/controllers/PaymentGetway.js new file mode 100644 index 0000000..28041f4 --- /dev/null +++ b/backend/api/controllers/PaymentGetway.js @@ -0,0 +1,78 @@ +const crypto = require('crypto') +const axios = require('axios') + +const paymentGetway = async (req, res) => { + console.log('paymentInitiated') + try { + + + // Payload structure for PhonePe API + const data = { + "merchantId": "PGTESTPAYUAT86", // Example Merchant ID + 'merchantTransactionId': `MT${Date.now()}`, // Dynamic Transaction ID + 'merchantUserId': "MUID123", + 'amount': 10000, // Amount in paise (100 rupees) + 'redirectUrl': "http://localhost:3000", + 'redirectMode': 'REDIRECT', + 'paymentInstrument': { + 'type': "PAY_PAGE", + }, + }; + + // Base64 encode the payload + const payLoad = JSON.stringify(data); + const base64Payload = Buffer.from(payLoad).toString("base64"); + + // Compute X-VERIFY checksum + const saltKey = "96434309-7796-489d-8924-ab56988a6076"; // Example salt key + const saltIndex = "1"; // Example salt index + const stringToHash = base64Payload + '/pg/v1/pay' + saltKey; + const sha256Hash = crypto.createHash('sha256').update(stringToHash).digest('hex'); + const checksum = sha256Hash + '###' + saltIndex; + + // Setup the request options + const options = { + method: 'POST', + url: 'https://api-preprod.phonepe.com/apis/pg-sandbox/pg/v1/pay', + headers: { + accept: 'application/json', // Expect a JSON response + 'Content-Type': 'application/json', + 'X-VERIFY': checksum, // X-VERIFY checksum header + }, + data: { + request: base64Payload, // Base64-encoded payload + }, + }; + + // Send the request using Axios + axios + .request(options) + .then(function (response) { + const redirectUrl = response.data.data.instrumentResponse.redirectInfo.url; + console.log('response.data: ', redirectUrl); + + return res.status(200).json({ + success:true, + url:redirectUrl + }); // Send back the API response + }) + .catch(function (error) { + console.error('Error response:', error); + res.status(500).json({ + success: false, + message: 'Payment gateway request failed', + error: error.response ? error.response.data : error.message, + }); + }); + + } catch (error) { + console.error('Error:', error.message); + res.status(500).json({ + success: false, + message: 'Server error', + error: error.message, + }); + } +}; + +module.exports = paymentGetway; \ No newline at end of file diff --git a/backend/server.js b/backend/server.js index a09b969..7287bbc 100644 --- a/backend/server.js +++ b/backend/server.js @@ -12,7 +12,7 @@ const helmet = require("helmet"); const authMiddleware = require("./api/middleware/authMiddleware"); require("dotenv").config(); const bodyParser = require('body-parser'); - +const payment = require("./api/controllers/PaymentGetway.js") // Connect to the database dbConnect(); @@ -39,7 +39,7 @@ app.use("/api/cart", authMiddleware, cartRoute); // Cart routes app.use("/api/product", productRoute); // Product routes app.use("/api/user", userRoute); // user routes app.use("/api/auth", authStatusRoute); // Check Auth Status - +app.use("/api/pay", payment) // // Rate limiting middleware // const limiter = rateLimit({ diff --git a/src/common/constants/apiConstants.js b/src/common/constants/apiConstants.js index a4d391d..f9f3fb1 100644 --- a/src/common/constants/apiConstants.js +++ b/src/common/constants/apiConstants.js @@ -1 +1,10 @@ -export const API_BASE_URL = 'http://localhost:8080/api'; +export const API_BASE_URL = 'http://localhost:8080'; + +const commonBackendURL = { + paymentGetway: { + url: `${API_BASE_URL}/api/pay`, + method: 'post' + }, + } + + export default commonBackendURL; \ No newline at end of file diff --git a/src/pages/Cart.jsx b/src/pages/Cart.jsx index f8fe301..a802bc9 100644 --- a/src/pages/Cart.jsx +++ b/src/pages/Cart.jsx @@ -10,7 +10,7 @@ import { LeftDivider } from '../styles/Divider'; import { useDispatch } from 'react-redux'; import { Box, useToast } from '@chakra-ui/react'; import { deleteCartItem, updateCartItem } from '../store/slices/cartSlice'; - +import commonBackendURL from '../common/constants/apiConstants.js' const Container = styled.div``; const Wrapper = styled.div` @@ -203,6 +203,38 @@ const Cart = () => { const totalPrice = cartItems.reduce((total, item) => total + item.price * item.quantity, 0); const toast = useToast(); const dispatch = useDispatch(); +// payment getway initiate and send data to backend + const initiatePayment = async () => { + try { + // Await the fetch to complete + const response = await fetch(commonBackendURL.paymentGetway.url, { + method: commonBackendURL.paymentGetway.method, + credentials: "include", + headers: { + "content-type": "application/json", + } + }); + + // Parse the response as JSON + const responseData = await response.json(); + + // Log the parsed response data + console.log('responseData:', responseData); + + // If the response contains a redirect URL, perform the redirection + if (responseData.success && responseData.url) { + const redirectUrl = responseData.url; + console.log('Redirecting to:', redirectUrl); + + // Perform the redirection + window.location.href = redirectUrl; + // onSuccessPayment(); + Cart(); + } + } catch (error) { + console.error('Error:', error); + } + } const handleQuantityChange = (productId, quantity) => { dispatch(updateCartItem({ productId, quantity })) @@ -275,7 +307,7 @@ const Cart = () => { Your Wishlist ({wishListItems?.length}) - CHECKOUT NOW + {initiatePayment()}}>CHECKOUT NOW @@ -319,7 +351,7 @@ const Cart = () => { Total $ {totalPrice} - +