如何将Express路由接收的价格参数传入Stripe create-checkout-session对象
问题根因
你当前配置的两个POST接口是完全独立的HTTP请求,HTTP协议本身无状态,/data路由里拿到的req.body[0].price不会自动传递给后续的/create-checkout-session请求,所以后者收到的请求体里根本没有对应数据,才会报读取undefined的price属性错误。同时你在/data路由里先调用了res.send()之后再调next()是无效的,响应已经返回给客户端,后续逻辑没法传递数据。
解决方案1:合并请求逻辑(最推荐,实现最简单)
直接把Stripe创建会话的逻辑放到/data路由里,不需要单独做两个接口,客户端提交蛋糕参数的时候直接返回结账链接即可,修改后的代码如下:
// 代码头部确保已经加了body解析中间件 app.use(express.json()); // 如果是表单提交还要加:app.use(express.urlencoded({ extended: true })); // 不需要单独的/create-checkout-session路由,直接在/data里处理所有逻辑 app.post('/data', async (req, res) => { console.log(req.body[0].price); // 此处已经能正确拿到价格 try { // 注意:Stripe的unit_amount单位是货币最小单位,英镑对应便士 // 如果拿到的price是英镑数值(比如7代表7英镑),需要乘以100再传入,避免少收款 const finalPrice = req.body[0].price * 100; const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: [ { price_data: { currency: "gbp", unit_amount: finalPrice, product_data: { name: "CakeItOrLeaveIt", }, }, quantity: 1, }, ], mode: "payment", success_url: `http://localhost:4242/success.html`, cancel_url: `http://localhost:4242/cancel.html`, }); // 直接返回会话url给前端,由前端执行跳转逻辑 res.json({ url: session.url }); } catch (e) { res.status(500).json({ error: e.message }); } }) app.listen(4242, () => console.log(`Node server listening on port 4242!`));
解决方案2:保留双接口的实现方案
如果业务流程必须要分两次请求,可以用express-session把价格存在服务端会话里,下次请求时读取:
- 先安装依赖:
npm install express-session - 调整代码如下:
const session = require('express-session'); // 配置session app.use(session({ secret: '自定义加密字符串', resave: false, saveUninitialized: true, cookie: { secure: false } // 开发环境设为false,生产环境启用https后改为true })) app.use(express.json()); app.post('/data', (req, res) => { console.log(req.body[0].price); // 把价格存入session req.session.cakePrice = req.body[0].price; res.send({message : "Successful request"}) }) app.post("/create-checkout-session", async (req, res) => { // 从session中读取价格 const cakePrice = req.session.cakePrice; if (!cakePrice) { return res.status(400).send('未获取到蛋糕价格,请先提交蛋糕参数'); } const finalPrice = cakePrice * 100; const session = await stripe.checkout.sessions.create({ payment_method_types: ["card"], line_items: [ { price_data: { currency: "gbp", unit_amount: finalPrice, product_data: { name: "CakeItOrLeaveIt", }, }, quantity: 1, }, ], mode: "payment", success_url: `http://localhost:4242/success.html`, cancel_url: `http://localhost:4242/cancel.html`, }); res.redirect(303, session.url); }); app.listen(4242, () => console.log(`Node server listening on port 4242!`));
内容的提问来源于stack exchange,提问作者Calum Bradley
相关产品推荐
相关产品推荐

