Stripe Webhook签名验证失败求助(本地正常线上报错)
Stripe Webhook签名验证失败(本地正常,Cloud Run部署后报错)
问题核心原因
Stripe Webhook的签名验证依赖原始未解析的HTTP请求体字节,你的代码中使用了req.body——如果Express全局配置了express.json()中间件,这个req.body已经是解析后的JSON对象,并非Stripe计算签名时用的原始字节,直接导致签名匹配失败。本地可能因中间件顺序或环境差异未触发解析,但Cloud Run环境下中间件正常生效,因此报错。
解决方案
1. 针对Webhook路由单独配置原始请求体解析
在Webhook路由上禁用默认JSON解析,改用express.raw()中间件获取原始Buffer:
const express = require('express'); // 调整路由,将raw中间件放在最前面 router.post("/orderupdate", express.raw({ type: "application/json" }), catchAsync(async (req, res) => { const payload = req.body; // 此时为原始Buffer,符合Stripe验证要求 const sig = req.headers['stripe-signature']; let event; try { event = stripe.webhooks.constructEvent(payload, sig, endpointSecret); } catch (e) { console.error("签名验证失败:", e); return res.status(400).send(`Webhook Error: ${e.message}`); } try { if (event.type === "checkout.session.completed") { // 你的业务逻辑代码 } } catch (e) { console.error("事件处理失败:", e); } res.status(200).end(); }))
2. 额外排查点
- 确认签名密钥正确性:检查
endpointSecret是否为Stripe Dashboard中对应Webhook的签名密钥(测试环境用测试密钥,生产环境用生产密钥,不可混用)。 - 中间件顺序:确保
express.raw()是Webhook路由的第一个中间件,避免日志、JSON解析等其他中间件提前修改请求体。 - Cloud Run环境检查:确认没有网关或负载均衡在转发请求时自动解析并修改JSON请求体,Stripe要求请求体必须和发送时完全一致。
内容的提问来源于stack exchange,提问作者Bartlomiej Dlugosz
相关产品推荐
相关产品推荐

