I’m encountering issues with Stripe payment processing in a client-server application. On the frontend, I’ve built a checkout form using @stripe/react-stripe-js and send payment data to the backend. However, there seems to be an issue with the amount sent from the client to the server. On the backend, I’ve set up Express.js routes to handle payments and explored Stripe’s payment intents logic. Despite ensuring proper Stripe API configuration, I’ve faced 500 Internal Server Errors during payment handling on the server. Additionally, I’ve noticed import errors related to the Stripe package in the client application.
[plugin:vite:import-analysis] Failed to resolve import "@stripe/react-stripe-js" from "srccomponentsCheckoutForm.jsx". Does the file exist?
C:/Users/Khaled/Desktop/pizza-si/client/src/components/CheckoutForm.jsx:1:52
9 | import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
10 | var _s = $RefreshSig$();
11 | import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
| ^
12 | import PropTypes from "prop-types";
13 | import { useDispatch } from "react-redux";
server.js:
const express = require("express");
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
const app = express();
app.use(express.json());
app.use(express.static("public"));
app.use("/", (req, res) => {
res.send("Server is running!");
});
app.get("/success", (req, res) => {
res.sendFile(__dirname + "/public/success.html");
});
app.get("/cancel", (req, res) => {
res.sendFile(__dirname + "/public/cancel.html");
});
app.post("/payment", async (req, res) => {
try {
const paymentIntent = await stripe.paymentIntents.create({
amount: req.body.amount,
currency: "usd",
});
console.log("Payment intent created:", paymentIntent.id);
res.status(200).send({ clientSecret: paymentIntent.client_secret });
} catch (error) {
console.error("Payment failed:", error);
res.status(500).send({ error: "Payment failed" });
}
});
app.listen(3001, () => {
console.log("Server is running on port 3001");
});
checkoutForm.jsx:
import { CardElement, useStripe, useElements } from "@stripe/react-stripe-js";
import PropTypes from "prop-types";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import {
startCheckout,
completeCheckout,
cancelCheckout,
} from "../redux/user/userSlice";
export default function CheckoutForm({ items, totalPrice }) {
const dispatch = useDispatch();
const navigate = useNavigate();
const stripe = useStripe(); // Add useStripe hook
const elements = useElements();
const handleSubmit = async (e) => {
e.preventDefault();
dispatch(startCheckout());
// Create a payment method using the CardElement
const { error, paymentMethod } = await stripe.createPaymentMethod({
type: "card",
card: elements.getElement(CardElement),
});
if (!error) {
// Send the payment method to your backend to create a payment intent
const response = await fetch("/create-payment-intent", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
payment_method_id: paymentMethod.id,
amount: totalPrice * 100, // Convert to cents
currency: "usd",
}),
});
const { clientSecret, error: paymentError } = await response.json();
if (clientSecret) {
const { paymentIntent, error: confirmError } =
await stripe.confirmCardPayment(clientSecret, {
payment_method: paymentMethod.id,
});
if (!confirmError) {
// If payment is successful, dispatch action to complete checkout and save payment details
dispatch(completeCheckout({ items, totalPrice }));
navigate("/success");
} else {
dispatch(cancelCheckout());
navigate("/cancel");
}
// Log the paymentIntent or handle it in some way
console.log(paymentIntent);
} else {
console.error(paymentError); // Log or handle payment errors
}
}
};
return (
<form onSubmit={handleSubmit}>
{/* ... */}
<CardElement />
{/* ... */}
</form>
);
}
CheckoutForm.propTypes = {
totalPrice: PropTypes.number,
items: PropTypes.array,
};
package.json for server:
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1",
"start": "node server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@stripe/react-stripe-js": "^2.3.2",
"@stripe/stripe-js": "^2.1.11",
"express": "^4.18.2",
"stripe": "^14.4.0"
}
}
package.json for client:
{
"name": "client",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview"
},
"dependencies": {
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.14.8",
"@reduxjs/toolkit": "^1.9.5",
"@stripe/stripe-js": "^1.29.0",
"firebase": "^10.4.0",
"framer-motion": "^10.16.4",
"i18next": "^23.5.1",
"i18next-browser-languagedetector": "^7.1.0",
"i18next-http-backend": "^2.2.2",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-firebase-hooks": "^5.1.1",
"react-i18next": "^13.2.2",
"react-icons": "^4.11.0",
"react-redux": "^8.1.2",
"react-router-dom": "^6.15.0",
"react-stripe-js": "^1.1.5",
"redux-persist": "^6.0.0",
"stripe": "^14.5.0"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@vitejs/plugin-react-swc": "^3.3.2",
"eslint": "^8.45.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"vite": "^4.4.5"
}
}
2
Answers
Did you install Stripe React via
npm install --save @stripe/react-stripe-js @stripe/stripe-js
? You may need to runnpm install
again.If so, is the package present in
/src/components
?It looks like Vite is looking in that directory for the script, so you may need to tell it to look elsewhere if you’ve installed
stripe/react-stripe-js
in another directory.A few things to check: