Here are some of the things I learned while trying to debug this.
- Stripe checkout uses AWS Cloudfront and it does not allow options requests (as per Stripe’s config)
- OPTIONS request are not sent to Stripe when I change the request type in the frontend to
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) - Best to avoid redirects when using React
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
}