You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:07:21