NextJS部署Vercel后Stripe Webhook签名匹配失败求助
解决Vercel部署NextJS应用后Stripe Webhook签名验证失败的问题
核心原因及解决方案
1. 禁用Next.js自动请求体解析(关键)
Next.js 13+的App Router默认会自动解析JSON请求体,这会破坏Stripe Webhook需要的原始未修改请求体,导致签名验证失败。在你的Webhook路由文件顶部添加以下配置:
export const config = { api: { bodyParser: false, }, };
2. 正确获取原始请求体
禁用自动解析后,使用micro库来获取原始Buffer(推荐Stripe官方文档方案),修正后的完整代码示例:
import { buffer } from "micro"; import { NextResponse } from "next/server"; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { apiVersion: "2023-08-16", }); const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; export const config = { api: { bodyParser: false, }, }; export async function POST(req) { const buf = await buffer(req); const sig = req.headers.get('stripe-signature'); let event; try { event = stripe.webhooks.constructEvent(buf, sig, webhookSecret); } catch (err) { console.log(`Stripe Webhook Error: ${err.message}`); return NextResponse.json({ received: false, error: err.message }, { status: 400 }); } // 处理你的Webhook事件逻辑 switch (event.type) { case 'payment_intent.succeeded': // 处理支付成功事件 break; // 其他事件类型处理 default: console.log(`Unhandled event type ${event.type}`); } return NextResponse.json({ received: true }); }
3. 验证Vercel环境变量配置
- 登录Vercel控制台,进入你的项目,确认
STRIPE_WEBHOOK_SECRET和STRIPE_SECRET_KEY已正确设置,注意Webhook密钥是Stripe控制台中Webhook端点的签名密钥,不是API密钥。 - 确保环境变量在生产环境(Production)中已启用,Vercel默认不会自动同步开发环境变量到生产,需要手动添加或同步。
4. 检查Stripe Webhook端点配置
- 在Stripe控制台中,确认Webhook的URL是Vercel部署后的完整HTTPS地址(如
https://your-vercel-app.vercel.app/api/webhooks/stripe)。 - 确保已勾选需要监听的事件类型,并且Stripe发送的请求没有被Vercel的防火墙或安全规则拦截(Vercel默认允许外部请求,但如果有自定义中间件需要检查是否修改了请求头)。
5. 排查自定义中间件干扰
如果你项目中使用了自定义中间件(middleware.ts),检查是否有修改请求体或请求头的逻辑,比如:
- 解析请求体后没有重新生成原始Buffer
- 修改了
stripe-signature请求头 - 对请求进行了压缩或修改编码
如果中间件必须处理请求,需要确保Webhook的路径被排除在中间件处理逻辑之外,比如在middleware.ts中添加:
export const config = { matcher: [ '/((?!api/webhooks/stripe).*)', // 排除Webhook路径 ], };
内容的提问来源于stack exchange,提问作者Benjamin Fogiel
相关产品推荐
相关产品推荐

