I am trying to integrate Stripe Checkout using the instructions given here https://stripe.com/docs/payments/accept-a-payment?integration=checkout for node.
I have followed their instructions to a tee and have updated the API key in the example with an actual (test) one from my account.
I am using React in the frontend and express in the backend. I have enabled cors.
The request from React to the backend succeeds and a preflight request is kicked off to stripe. The preflight response from stripe is a 403 and the actual request is blocked with a CORS error - PreflightMissingAllowOriginHeader
const express = require("express");
const app = express();
const cors = require("cors");
const stripe = require("stripe")(
process.env.STRIPE_SECRET_KEY
);
app.use(
cors({
origin: ["http://localhost:8000", "https://checkout.stripe.com"],
})
);
app.post("/create-checkout-session", async (req, res) => {
console.log('getting here 1')
const session = await stripe.checkout.sessions.create({
payment_method_types: ["card"],
line_items: [
{
price_data: {
currency: "usd",
product_data: {
name: "T-shirt",
},
unit_amount: 2000,
},
quantity: 1,
},
],
mode: "payment",
success_url: "http://localhost:4242/success.html",
cancel_url: "http://localhost:4242/cancel.html",
});
console.log('getting here 2')
res.redirect(303, session.url);
});
app.listen(4242, () => console.log(`Listening on port ${4242}!`));
handleClick = () => {
const res = fetch(`${process.env.BACKEND_API_URL}/create-checkout-session`, {
method: 'POST',
headers: {
"Content-Type": 'text/html'
}
})
}
Here are some of the things I learned while trying to debug this.
text/plain
. (Yes, that's right, after my server returns the 303 with Stripe's url, Chrome does not send an OPTIONS request to Stripe)Here is the updated backend and frontend code, respectively, that solved the problem
app.post("/create-checkout-session", async (req, res) => {
const session = await stripe.checkout.sessions.create({
payment_method_types: ["card"],
line_items: [
{
price_data: {
currency: "usd",
product_data: {
name: "T-shirt",
},
unit_amount: 2000,
},
quantity: 1,
},
],
mode: "payment",
success_url: "http://localhost:8000/success",
cancel_url: "http://localhost:8000/cancel",
});
res.json({url: session.url}) // <-- this is the changed line
});
handleClick = async () => {
const res = await fetch(`${process.env.BACKEND_API_URL}/create-checkout-session`, {
method: 'POST',
headers: {
"Content-Type": 'application/json'
}
})
const body = await res.json()
window.location.href = body.url
}