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

Express.js中Stripe Webhook出现400 Bad Request错误求助

解决Express + Stripe Webhook 400 Bad Request错误

你的400错误来自Stripe Webhook的签名验证失败,以下是针对性的排查和修复方案:

1. 确认Webhook签名密钥正确

  • 你当前硬编码了endpointSecret,首先要确保这个值是Stripe后台对应Webhook端点的签名密钥(不是API密钥)。
  • 测试环境和生产环境的签名密钥是分开的,不要混淆。建议把密钥放到.env文件中,通过环境变量读取,避免硬编码:
    const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
    

2. 防止请求体被重复解析

Express的全局express.json()中间件会把请求体解析为JSON对象,但Stripe的Webhook需要原始的二进制请求体来验证签名。如果你的app.use(express.json())在app.use("/api/stripe", stripeRouter)之前执行,会导致request.body已经被解析,无法通过签名验证。

修复方案:

  • 调整中间件顺序,让Webhook路由优先使用express.raw()解析,跳过全局的express.json():
    // index.js
    // 先单独挂载Webhook路由,使用raw解析
    app.use(
      "/api/stripe/webhook",
      express.raw({ type: "application/json" }),
      stripeRouter
    );
    // 再挂载全局json解析和其他Stripe路由
    app.use(express.json());
    app.use("/api/stripe", stripeRouter);
    

3. 检查Webhook转发配置(测试阶段)

如果你用Stripe CLI测试Webhook,确保:

  • 转发命令的端点路径和代码完全一致,比如:
    stripe listen --forward-to localhost:3000/api/stripe/webhook
    
  • 确认CLI使用的是对应环境的API密钥(测试环境用测试密钥,生产用生产密钥),可通过--api-key参数指定。

4. 确保签名请求头完整传递

如果你的应用部署在反向代理(如Nginx)或托管平台上,要确保stripe-signature请求头没有被修改或丢弃。比如Nginx需要配置proxy_set_header stripe-signature $http_stripe_signature;来传递该头。

额外优化建议

  • 用Checkout流程时,更推荐监听checkout.session.completed事件(而非payment_intent.succeeded),因为这个事件包含完整的Checkout会话信息,更适合处理订单逻辑:
    switch (event.type) {
        case "checkout.session.completed":
            const checkoutSession = event.data.object;
            // 在这里处理订单创建、通知用户等逻辑
            break;
        // ...其他事件
    }
    

内容的提问来源于stack exchange,提问作者Can Do

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:30:40