Stripe订阅系统Webhook签名验证失败求助
解决Stripe Webhook签名验证失败问题
问题根源
错误提示明确指出:签名验证需要原始请求体(字符串或Buffer),但你的代码中request.body已经被解析成了JavaScript对象。这是因为你的Express应用大概率全局注册了express.json()中间件,且该中间件在webhook路由之前执行,提前把请求体解析成了对象,导致stripe.webhooks.constructEvent无法获取签名所需的原始数据。
解决方案
调整路由与全局中间件的注册顺序,让webhook路由优先使用express.raw中间件处理请求,保留原始请求体:
- 修改代码结构:将webhook路由的注册放在全局
express.json()中间件之前,示例如下:
// 先注册webhook路由,使用raw中间件保留原始请求体 app.post( '/webhook', express.raw({ type: 'application/json' }), (request, response) => { let event = request.body; const endpointSecret = 'whsec_.....'; if (endpointSecret) { const signature = request.headers['stripe-signature']; try { event = stripe.webhooks.constructEvent( request.body, signature, endpointSecret ); } catch (err) { console.log(`⚠️ Webhook signature verification failed.`, err.message); return response.sendStatus(400); } } let subscription; let status; switch (event.type) { case 'customer.subscription.created': subscription = event.data.object; status = subscription.status; console.log(`Subscription status is ${status}.`); break; default: console.log(`Unhandled event type ${event.type}.`); } response.send(); } ); // 再注册全局json中间件,处理其他API路由的JSON解析 app.use(express.json());
- 验证逻辑:这样webhook请求会先经过
express.raw处理,request.body保持为Buffer类型,满足constructEvent的签名验证要求;其他路由仍能正常使用express.json()解析请求体。
额外检查点
- 确认你的Stripe端点密钥(
whsec_...)与Stripe Dashboard中配置的完全一致 - 测试时使用Stripe CLI发送测试webhook事件,避免本地环境的请求体篡改问题
内容的提问来源于stack exchange,提问作者Adalbert Steiner
相关产品推荐
相关产品推荐

