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

使用Adonis.js开发Stripe Webhook验证中间件持续报错求助

排查Adonis.js中Stripe Webhook签名验证失败的问题

我之前在Adonis.js里处理Stripe Webhook签名验证时也踩过类似的坑,结合你的代码,几个关键排查点和解决方案可以参考:

1. 确保请求体未被篡改(核心问题)

Stripe的签名验证完全基于原始未解析的请求体生成,如果Adonis默认的bodyparser中间件提前解析了请求体,再通过request.raw()拿到的内容会和Stripe发送的原始数据不一致,直接导致签名匹配失败。

解决方法:

  • 在Webhook路由定义中禁用bodyparser:
// 以Adonis v5为例,路由文件中配置
Route.post('/stripe/webhook', 'StripeWebhookController.handle')
  .middleware(['stripe-webhook'])
  .disableBodyParser();
  • 正确获取原始请求体:
    • Adonis v4:直接使用request.raw()
    • Adonis v5:需要异步获取await request.rawBody()

2. 检查签名密钥的获取逻辑

你的代码里根据事件类型webhookEvent拼接密钥,但Stripe的Webhook签名密钥是绑定到具体的Webhook端点(URL),而非单个事件类型的。如果你的配置逻辑是按事件类型分配密钥,大概率会用错密钥导致验证失败。

如果确实需要按事件类型区分,要注意顺序:禁用bodyparser后request.post().type无法直接获取事件类型,得先完成签名验证,再解析事件体拿到类型:

const rawBody = await request.rawBody(); // 或request.raw()
const signature = request.header('stripe-signature');
// 先使用端点对应的通用密钥验证
const signingSecret = Config.get('stripe.webhook_secret'); 
try {
  const event = Stripe.webhooks.constructEvent(rawBody, signature, signingSecret);
  // 验证通过后再获取事件类型
  const webhookEvent = event.type;
  // 后续业务逻辑...
  request.stripeEvent = event;
  await next();
} catch (err) {
  console.error('Stripe验证错误详情:', err.message);
  return response.status(400).send(`Webhook Error: ${err.message}`);
}

3. 添加错误捕获,明确失败原因

你当前的代码没有捕获constructEvent抛出的错误,根本不知道是签名不匹配、密钥错误还是签名过期等具体问题。添加try-catch后,控制台会输出详细错误信息,帮你快速定位问题。

额外验证步骤

  • 确认Stripe Dashboard中配置的Webhook端点URL和你本地/服务器的URL完全一致(包括http/https)
  • 确认Stripe Dashboard里的签名密钥和你配置文件中的whsec_xxxx完全一致,没有空格或拼写错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:26:15