Next.js 14集成Stripe CLI时Webhook出现404错误的原因
Next.js 14集成Stripe Webhook返回404问题解决
核心原因
Next.js 14的App Router对API路由有严格结构要求:必须放在app/api/[路由名称]/route.ts路径下,且需通过导出POST/GET等函数处理请求。你当前的文件路径/app/api/webhook.tsx不符合规范,导致Stripe转发的请求无法找到对应端点,返回404。
解决方案
1. 调整文件结构
将原/app/api/webhook.tsx移动到/app/api/webhook/route.ts,确保路径符合App Router的API路由规则。
2. 适配App Router的API路由代码
修改route.ts内容,适配App Router的请求处理逻辑(不再使用NextApiRequest/NextApiResponse,需关闭自动解析请求体以验证Stripe签名):
import Stripe from "stripe"; import getRawBody from "raw-body"; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string, { apiVersion: '2023-10-16' }); const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET as string; // 关闭Next.js自动解析请求体,Stripe需要原始body来验证签名 export const config = { api: { bodyParser: false, }, }; export async function POST(request: Request) { try { // 获取原始请求体 const rawBody = await getRawBody(request); const signature = request.headers.get('stripe-signature'); if (!signature) { return new Response('Missing stripe-signature header', { status: 400 }); } let event; try { event = stripe.webhooks.constructEvent(rawBody, signature, webhookSecret); } catch (error: any) { return new Response(`Webhook signature verification failed: ${error.message}`, { status: 400 }); } // 处理checkout.session.completed事件 if (event.type === 'checkout.session.completed') { const session = event.data.object as Stripe.Checkout.Session; try { const sessionWithLineItems = await stripe.checkout.sessions.retrieve(session.id, { expand: ['line_items'] }); console.log('订单详情:', sessionWithLineItems.line_items?.data); } catch (error) { return new Response('Failed to retrieve session line items', { status: 500 }); } } return new Response('Webhook handled successfully', { status: 200 }); } catch (error: any) { return new Response(`Webhook error: ${error.message}`, { status: 500 }); } }
3. 验证关键配置
- 确认
.env.local中的STRIPE_WEBHOOK_SECRET是Stripe CLI启动时输出的webhook签名密钥(不是Stripe API密钥) - 保持Stripe CLI转发命令不变:
stripe listen --forward-to localhost:3000/api/webhook - 重启Next.js开发服务器,确保路由变更生效
额外说明
- App Router中无需使用
dynamicParams,而是通过export const config配置API路由行为 - 必须关闭
bodyParser,否则Next.js会自动解析请求体,导致Stripe无法验证签名 - 支付成功后,Stripe CLI终端应返回
200状态码,说明webhook已正常接收
内容的提问来源于stack exchange,提问作者DigiLeon
相关产品推荐
相关产品推荐

