Strapi如何整合Stripe支付订单控制器与用户关联多表单提交功能
整合后的完整订单控制器代码
const stripe = require('stripe')('xxxvxx'); // 替换为你自己的Stripe密钥 const { parseMultipartData, sanitizeEntity } = require('strapi-utils'); module.exports = { create: async ctx => { let orderData; let orderFiles = null; // 统一处理两种请求格式的数据 if (ctx.is('multipart')) { const { data, files } = parseMultipartData(ctx); // 绑定当前登录用户到订单,字段名和订单模型的用户关联字段保持一致 data.user = ctx.state.user.id; orderData = data; orderFiles = files; } else { ctx.request.body.user = ctx.state.user.id; orderData = ctx.request.body; } // 从统一处理后的数据中提取支付所需参数 const { address, amount, product, token } = orderData; try { // Stripe 扣费流程 await stripe.customers .create({ email: ctx.state.user.email, source: token }) .then((customer) => { return stripe.charges.create({ amount: amount * 100, // 金额转换为美分 currency: 'usd', description: `订单 ${new Date()} 所属用户ID:${ctx.state.user.id}`, customer: customer.id }); }); // 扣费成功后创建订单到数据库 try { const order = await strapi.services.order.create( orderData, orderFiles ? { files: orderFiles } : {} ); // 订单创建成功后发送通知邮件 if (order.id) { await strapi.plugins['email'].services.email.send({ to: ctx.state.user.email, subject: '感谢您的购买', text: ` 我们已通过Stripe从您的信用卡扣除${order.amount}美元。 配送地址:${order.address} `, }); } // 返回经过脱敏处理的订单数据,避免敏感字段泄露 return sanitizeEntity(order, { model: strapi.models.order }); } catch (dbErr) { ctx.response.status = 500; ctx.body = { error: '订单创建失败,请联系客服', details: dbErr.message }; console.error('订单数据库写入错误:', dbErr); } } catch (stripeErr) { ctx.response.status = 402; ctx.body = { error: '支付失败,请检查支付信息', details: stripeErr.message }; console.error('Stripe支付错误:', stripeErr); } } };
核心调整说明
- 统一请求数据处理逻辑:新增multipart表单适配,普通JSON提交和带文件的表单提交都可以正常解析
- 自动关联登录用户:数据解析阶段就把当前登录用户ID写入订单关联字段,无需前端传参,避免伪造用户提交,同时Strapi后台可直接展示每个订单对应的购买用户
- 兼容文件上传:如果订单需要上传凭证、收据等附件,直接通过multipart表单提交即可,文件会自动关联到对应订单
- 规范返回值:新增sanitizeEntity处理返回结果,自动过滤敏感字段,符合Strapi官方开发规范
- 完善错误处理:区分支付错误和数据库错误,返回对应状态码和提示,便于前端做交互处理
注意事项
- 请先确认订单模型(路径
/api/order/models/order.settings.json)中已经配置了和用户表的关联字段,代码中使用的关联字段名为user,如果你的字段名是users_permissions_user,请把代码中所有data.user、ctx.request.body.user替换为对应字段名 - Stripe密钥不要硬编码在代码中,建议配置到Strapi环境变量中读取,避免密钥泄露
- 邮件模板可根据自身业务需求自行调整内容
内容的提问来源于stack exchange,提问作者lsfsteve
相关产品推荐
相关产品推荐

