Stripe Webhook无法读取Express请求原始Body,报400错误求助
解决Stripe Webhook "payload must be provided as a string or a Buffer"错误
你的问题核心是Stripe Webhook签名验证依赖原始未解析的请求体,但你用bodyParser.json()把请求体解析成了JSON对象,导致constructEvent无法正确验证签名。
修正步骤:
- 移除webhook路由上的
bodyParser.json(),替换为bodyParser.raw({ type: 'application/json' }),这样获取到的request.body是原始Buffer,符合Stripe的要求。 - 确保webhook路由的中间件配置在其他
express.json()或bodyParser.json()中间件之前,避免请求体被提前解析。
修正后的代码:
dotenv.config() const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY) const bodyParser = require('body-parser') // 确保已安装并引入body-parser const app = express() app.use(morgan("dev")) app.use( cors({ origin: process.env.ORIN, credentials: true, optionsSuccessStatus: 200, }) ) // Webhook路由使用raw中间件获取原始请求体 app.post("/webhook", bodyParser.raw({ type: 'application/json' }), (request, response) => { const payload = request.body // 此时payload是Buffer类型 const sig = request.headers["stripe-signature"] let event try { event = stripe.webhooks.constructEvent( payload, sig, process.env.STRIPE_ENDPOINT_SECRET ) if (event.type === "checkout.session.completed") { console.log("Session completed successfully") } } catch (err) { return response.status(400).send(`Webhook Error: ${err.message}`) } response.status(200).end() }) app.use(cookieParser()) app.use(express.json({ limit: "50mb" })) //Rest of endpoints
补充说明:
- 如果你的Express版本是v4.16+,也可以用
express.raw({ type: 'application/json' })替代bodyParser.raw,效果一致。 - 绝对不能在webhook路由之前使用任何会解析请求体的中间件(比如
express.json()、bodyParser.json()),否则原始请求体被修改后签名验证必然失败。
内容的提问来源于stack exchange,提问作者dacalite
相关产品推荐
相关产品推荐

