Search code examples
node.jsreactjscorsstripe-payments

ReactJS / NodeJS call stripe api


I'm making a payment tool using Stripe's api. Only when I make my fetch order I get this error:

Access to fetch at 'https://checkout.stripe.com/c/pay/cs_test_a17M3P9xrCIrTMFi9s6BXK3uPIMuCsLMZTNZsGggylcIN41Am2xjHz1OIA#fidkdWxOYHwnPyd1blpxYHZxWjA0S2xjTV1EdnBLRlJMSEthR2d9YGhTZF9tcmpwX2tXajdJcjVdMmZnZEI3U1E8T3I3QTFVRmN8d25OMTxxTk9yc2xrY3d1X1FjTnx8X0lnQEtvcTBVUWNkNTVWVU00cWZWPCcpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl' (redirected from 'http://localhost:5000/api/stripepayement') from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Someone could explain me how can i get this error please ? I tried something but the line res.redirect(303, session.url); give me an error and doesn't redirect me to the stripe payement page. Here's my code:

server.js:

const stripePayement = require("./routes/stripePayement");
app.use(
  cors({
    origin: true,
    methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
    credentials: true,
  })
);
app.use("/api/stripepayement", stripePayement);

stripepayement.js:

const express = require("express");
const router = express.Router();
const bodyParser = require("body-parser");
const stripe = require("stripe")(
  "STRIPE-KEY"
);
router.use(bodyParser.json());

const YOUR_DOMAIN = "http://localhost:3000";

router.post("/", async (req, res) => {
  const numberofDays = req.body.totalPrice;
  console.log("Days: ", numberofDays);

  try {
    const session = await stripe.checkout.sessions.create({
      line_items: [
        {
          price: "price_1Nj0xIAsuNCWIMNdoD6PaVh5",
          quantity: numberofDays && numberofDays > 0 ? numberofDays : 1,
        },
      ],
      mode: "payment",
      success_url: `${YOUR_DOMAIN}?success=true`,
      cancel_url: `${YOUR_DOMAIN}?canceled=true`,
      automatic_tax: {enabled: true},
    });
    console.log("Successfully created session", session);
    res.redirect(303, session.url);
  } catch (error) {
    console.error("Erreur lors de la création de la session Stripe:", error);
    res.status(500).json({error: "Une erreur est survenue lors du paiement."});
  }
});
module.exports = router;

clientPage.js:

const handlePayment = async (e) => {
    e.preventDefault();
    try {
      const response = fetch("http://localhost:5000/api/stripepayement", {
        method: "POST",
        headers: {
          "Content-Type": "application/json", // Assurez-vous que le type de contenu est correct
        },
        body: JSON.stringify({
          totalPrice: numberOfDaysTmp,
        }),
      });

      const data = await response.json();
      console.log("REPONSE/ ", data);
      // console.log(data);
    } catch (error) {
      console.error("Erreur lors du paiement:", error);
    }
  };

 <form onSubmit={(e) => handlePayment(e)}>

Solution

  • Don't use both fetch and a redirect serverside, this is why you're getting this CORS issue.

    -Preferably, just use a form-submit to post data up from the client to your server, then redirect serverside.
    The issue with fetch (same with xmlHttpRequest for that matter) is that you're intending to redirect serverside, but fetch is bringing a response back to the client.

    -If you need to bring the information back to the client for a frontend redirect (for whatever reason), then encode the session data and pass it down, don't redirect serverside at all.
    With the data you have on the frontend, you can either use some window.location method to redirect or Stripe's own redirectToCheckout function:
    https://stripe.com/docs/js/deprecated/redirect_to_checkout

    Just check Stripe's quick build to help:
    https://stripe.com/docs/checkout/quickstart