如何修复Stripe报错:未提供stripe-signature请求头
解决Strapi中Stripe Webhook签名验证报错:No stripe-signature header value was provided
问题分析
你的Webhook能正常接收事件但签名验证失败,核心原因是Strapi默认会自动解析JSON请求体,导致原始请求体被修改,同时未禁用默认解析器时,验证用的body与Stripe发送的原始body不一致,最终触发签名验证错误。
解决方案
1. 修改Webhook路由配置,禁用默认body解析器
在route/order.js的Webhook路由中添加parser: false,阻止Strapi自动解析请求体,保留原始的raw body:
{ method: 'POST', path: '/orders/stripe-webhook', handler: 'order.handleWebhook', config: { auth: false, parser: false, // 关键:禁用默认的body解析中间件 }, },
2. 调整Webhook处理函数,使用原始请求体验证签名
修改handleWebhook函数,手动读取原始请求体(而非使用Strapi解析后的ctx.request.body),确保签名验证使用的body与Stripe发送的完全一致:
async handleWebhook(ctx) { const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET; const signature = ctx.request.headers['stripe-signature']; // 读取原始未修改的请求体 const rawBody = await new Promise((resolve, reject) => { let data = ''; ctx.req.on('data', chunk => data += chunk); ctx.req.on('end', () => resolve(data)); ctx.req.on('error', reject); }); try { // 使用原始body进行签名验证 const event = stripe.webhooks.constructEvent(rawBody, signature, endpointSecret); if (event.type === 'payment_intent.succeeded') { const paymentIntent = event.data.object; console.log('Pago exitoso:', paymentIntent); } ctx.status = 200; ctx.body = 'Webhook recibido correctamente'; } catch (err) { console.error('Error al procesar el webhook:', err.message); ctx.status = 400; ctx.body = `Error del webhook: ${err.message}`; } }
3. 额外验证步骤
- 确认环境变量
STRIPE_WEBHOOK_SECRET的值是Stripe CLI生成的whsec_开头的密钥,无复制错误 - 重启Strapi服务,确保路由配置生效
- 重新运行Stripe CLI监听命令:
stripe listen --forward-to http://localhost:1337/api/orders/stripe-webhook,再用stripe trigger payment_intent.succeeded测试
内容的提问来源于stack exchange,提问作者EdKane
相关产品推荐
相关产品推荐

