Stripe Checkout 示例 运行 从本地主机进入 CORS 错误
Stripe Checkout example running into CORS error from localhost
我正在尝试使用此处给出的说明 https://stripe.com/docs/payments/accept-a-payment?integration=checkout 为节点集成 Stripe Checkout。
我已按照他们的说明进行操作,并已将示例中的 API 密钥更新为我帐户中的实际(测试)密钥。
我在前端使用 React,在后端使用 express。我启用了cors。
React 向后端的请求成功,开始预检请求到条带化。来自 stripe 的预检响应是 403,实际请求因 CORS 错误而被阻止 - 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'
}
})
}
以下是我在尝试调试时学到的一些东西。
- Stripe 结账使用 AWS Cloudfront,它不允许选项请求(根据 Stripe 的配置)
- 当我将前端的请求类型更改为
text/plain
时,OPTIONS 请求未发送到 Stripe。 (是的,没错,在我的服务器 returns 带有 Stripe 的 url 的 303 后, Chrome 没有向 Stripe 发送 OPTIONS 请求)
- 使用 React 时最好避免重定向
这里分别是解决问题的更新后的后端和前端代码
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
}
我正在尝试使用此处给出的说明 https://stripe.com/docs/payments/accept-a-payment?integration=checkout 为节点集成 Stripe Checkout。
我已按照他们的说明进行操作,并已将示例中的 API 密钥更新为我帐户中的实际(测试)密钥。
我在前端使用 React,在后端使用 express。我启用了cors。
React 向后端的请求成功,开始预检请求到条带化。来自 stripe 的预检响应是 403,实际请求因 CORS 错误而被阻止 - 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'
}
})
}
以下是我在尝试调试时学到的一些东西。
- Stripe 结账使用 AWS Cloudfront,它不允许选项请求(根据 Stripe 的配置)
- 当我将前端的请求类型更改为
text/plain
时,OPTIONS 请求未发送到 Stripe。 (是的,没错,在我的服务器 returns 带有 Stripe 的 url 的 303 后, Chrome 没有向 Stripe 发送 OPTIONS 请求) - 使用 React 时最好避免重定向
这里分别是解决问题的更新后的后端和前端代码
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
}