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

Stripe订阅系统Webhook签名验证失败求助

解决Stripe Webhook签名验证失败问题

问题根源

错误提示明确指出:签名验证需要原始请求体(字符串或Buffer),但你的代码中request.body已经被解析成了JavaScript对象。这是因为你的Express应用大概率全局注册了express.json()中间件,且该中间件在webhook路由之前执行,提前把请求体解析成了对象,导致stripe.webhooks.constructEvent无法获取签名所需的原始数据。

解决方案

调整路由与全局中间件的注册顺序,让webhook路由优先使用express.raw中间件处理请求,保留原始请求体:

  1. 修改代码结构:将webhook路由的注册放在全局express.json()中间件之前,示例如下:
// 先注册webhook路由,使用raw中间件保留原始请求体
app.post(
  '/webhook',
  express.raw({ type: 'application/json' }),
  (request, response) => {
    let event = request.body;

    const endpointSecret = 'whsec_.....';

    if (endpointSecret) {
      const signature = request.headers['stripe-signature'];
      try {
        event = stripe.webhooks.constructEvent(
          request.body,
          signature,
          endpointSecret
        );
      } catch (err) {
        console.log(`⚠️  Webhook signature verification failed.`, err.message);
        return response.sendStatus(400);
      }
    }
    let subscription;
    let status;

    switch (event.type) {
      case 'customer.subscription.created':
        subscription = event.data.object;
        status = subscription.status;
        console.log(`Subscription status is ${status}.`);
        break;
      default:
        console.log(`Unhandled event type ${event.type}.`);
    }
    response.send();
  }
);

// 再注册全局json中间件,处理其他API路由的JSON解析
app.use(express.json());
  1. 验证逻辑:这样webhook请求会先经过express.raw处理,request.body保持为Buffer类型,满足constructEvent的签名验证要求;其他路由仍能正常使用express.json()解析请求体。

额外检查点

  • 确认你的Stripe端点密钥(whsec_...)与Stripe Dashboard中配置的完全一致
  • 测试时使用Stripe CLI发送测试webhook事件,避免本地环境的请求体篡改问题

内容的提问来源于stack exchange,提问作者Adalbert Steiner

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 18:52:47