skip to Main Content

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


  1. Did you install Stripe React via npm install --save @stripe/react-stripe-js @stripe/stripe-js? You may need to run npm 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.

    Login or Signup to reply.
  2. A few things to check:

    • Ensure client-server Stripe package version compatibility
    • Validate incoming request data on the server with logging
    • Check CORS settings if client and server are on different domains (or ports in this case).
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search