I have been working on processing a connection to a payment gateway and have run into a fetch issue.
I have been following this guide https://www.knowledgehut.com/blog/web-development/stripe-node-js
But I have run into a fetch error and I am unsure of how to proceed.
below is my check out modal component where the items in the cart are shown, a user can see the items added to the cart and remove them and this is where the payment is supposed to be processed.
import * as React from 'react';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
import Modal from '@mui/material/Modal';
import products from './product'
import { useContext } from 'react';
import { Elements } from "@stripe/react-stripe-js";
import { useState, useEffect} from 'react';
import { loadStripe } from "@stripe/stripe-js";
import cart from '../context/cart'
import { CartContext } from '../context/cart';
const style = {
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: "100%",
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 4,
};
export default function BasicModal() {
const [open, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
const stripePromise = loadStripe("pk_test_35p114pH8oNuHX72SmrvsFqh00Azv3ZaIA");
const { cartItems, addToCart, removeFromCart, clearCart, getCartTotal } = useContext(CartContext)
useEffect(() => {
// storing input name
localStorage.getItem("cartItems", JSON.stringify(cartItems));
}, [cartItems])
// payment is processed here
const makePayment = async () => {
const stripe = await loadStripe("pk_test_35p");
const body = { cartItems };
const headers = {
"Content-Type": "application/json",
};
const response = await fetch(
"localhost:8000/api/create-checkout-session",
{
method: "POST",
headers: headers,
body: JSON.stringify(body),
}
);
const session = await response.json();
const result = stripe.redirectToCheckout({
sessionId: session.id,
});
if (result.error) {
console.log(result.error);
}
};
return (
<div>
<Button onClick={handleOpen} >
({cartItems.length})
Check Out</Button>
<Modal
disableScrollLock={true}
fullScreen={true}
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box sx={style}>
<>
<div className="flex-col flex items-center bg-white gap-8 p-10 text-black text-sm">
<h1 className="text-2xl font-bold">Cart</h1>
<div className="flex flex-col gap-4">
{cartItems.map((item) => (
<div className="flex justify-between items-center" key={item.id}>
<div className="flex gap-4">
<img src={item.imageId} alt={item.title} className="rounded-md h-24" />
<div className="flex flex-col">
<h1 className="text-lg font-bold">{item.title}</h1>
<p className="text-gray-600">{item.price}</p>
<p className="text-gray-600">{item.description}</p>
</div>
</div>
<div className="flex gap-4">
<button
className="px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700"
onClick={() => {
addToCart(item)
}}
>
+
</button>
<p>{item.quantity}</p>
<button
className="px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700"
onClick={() => {
removeFromCart(item)
}}
>
-
</button>
</div>
</div>
))}
</div>
{
cartItems.length > 0 ? (
<div className="flex flex-col justify-between items-center">
<h1 className="text-lg font-bold">Total: ${getCartTotal()}</h1>
<button
className="px-4 py-2 bg-gray-800 text-white text-xs font-bold uppercase rounded hover:bg-gray-700 focus:outline-none focus:bg-gray-700"
onClick={() => {
clearCart()
}}
>
Clear cart
</button>
<Button variant="primary" onClick={makePayment} >Check out
</Button>
</div>
) : (
<>
<h1 className="text-lg font-bold">Your cart is empty</h1>
</>
)
}
</div>
<div class="col d-flex justify-content-center">
</div>
</>
</Box>
</Modal>
</div>
);
}
below is my node server where I am trying to process the back end
const cors = require("cors");
const express = require("express");
const stripe = require("stripe")("sMK");
const app = express();
// Middlewares here
app.use(express.json());
// Routes here
app.get("/", (req, res) => {
res.send("Hello World");
});
app.use(cors({origin: "*",}))
// Listen
app.listen(8000, () => {
console.log("Server started at port 8000");
});
app.post("/api/create-checkout-session", async (req, res) => {
const { product } = req.body;
const session = await stripe.checkout.sessions.create({
payment_method_types: ["card"],
line_items: [
{
price_data: {
currency: "inr",
product_data: {
name: product.name,
},
unit_amount: product.price * 100,
},
quantity: product.quantity,
},
],
mode: "payment",
success_url: "http://localhost:3000/success",
cancel_url: "http://localhost:3000/failure",
});
res.json({ id: session.id });
});
Your fetch command needs to specify the URL scheme, which for localhost
should be http:
.
Try changing this
const response = await fetch(
"localhost:8000/api/create-checkout-session",
{
method: "POST",
headers: headers,
body: JSON.stringify(body),
}
);
to this
const response = await fetch(
"http://localhost:8000/api/create-checkout-session",
{
method: "POST",
headers: headers,
body: JSON.stringify(body),
}
);