NextJS 14.2.3中Stripe Webhook签名验证失败求助
解决Next.js 14.2.3 App Router中Stripe Webhook部署后签名验证失败的问题
核心问题本质
本地正常但部署后报错,根源是部署环境中请求体被自动解析或修改——Stripe的签名验证依赖原始请求体的字节级一致性,任何解析、编码转换都会破坏验证逻辑。
分步解决方案
1. 强制禁用Next.js自动请求体解析
Next.js App Router默认会自动解析JSON请求体,这会修改原始内容。在你的route.ts顶部添加配置,确保能拿到原始请求的Buffer:
import { NextResponse } from 'next/server'; import Stripe from 'stripe'; // 关键配置:禁用自动解析,保留原始请求体 export const config = { api: { bodyParser: false, }, }; export async function POST(req: Request) { let event: Stripe.Event; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string, { apiVersion: '2024-04-10', // 必须匹配你Stripe控制台使用的API版本 }); try { // 读取原始请求体的Buffer(不能用req.text(),避免编码转换) const rawBody = await req.arrayBuffer(); const signature = req.headers.get('stripe-signature') as string; const webhookSecret = process.env.STRIPE_WEBHOOK_KEY as string; event = stripe.webhooks.constructEvent( Buffer.from(rawBody), signature, webhookSecret ); // 这里添加你的事件处理逻辑,示例: switch (event.type) { case 'checkout.session.completed': const session = event.data.object as Stripe.Checkout.Session; console.log('支付完成,会话ID:', session.id); // 比如更新数据库订单状态、发送用户通知等 break; default: console.log(`未处理事件类型: ${event.type}`); } return NextResponse.json({ message: 'Webhook调用成功' }); } catch (error) { const errorMsg = error instanceof Error ? error.message : '未知错误'; console.error('Webhook验证失败:', errorMsg); return NextResponse.json({ message: errorMsg }, { status: 400 }); } }
2. 排查部署环境的中间环节修改
- Vercel部署:默认不会修改请求体,但如果有自定义中间件,确保中间件没有提前读取或修改请求体(比如不要在中间件中调用
req.json()或req.text())。 - CDN/反向代理(如Cloudflare):配置CDN禁用请求体压缩、自动格式化,确保Stripe发送的原始字节流完整传递到你的端点。
3. 验证环境变量准确性
- 确认部署环境中
STRIPE_WEBHOOK_KEY是Stripe控制台里对应Webhook端点的签名密钥(不是API密钥),复制时不要带多余空格或换行。 - 确保
STRIPE_SECRET_KEY权限足够,且Stripe实例的apiVersion和控制台设置的版本完全一致。
4. 部署后测试验证
用Stripe CLI直接测试部署后的端点:
stripe listen --forward-to https://你的部署域名/api/webhook
触发测试事件(比如checkout.session.completed),查看日志是否验证成功。
内容的提问来源于stack exchange,提问作者Shahbaj Alam
相关产品推荐
相关产品推荐

