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

Node.js中为HubSpot与Stripe API适配express.raw的问题咨询

问题描述

我正在搭建一款运行于平台的应用,需接收应用的webhook并调用API执行操作。多数功能使用HubSpot API实现,支付及支付状态验证使用Stripe API,整体基于Node.js的Express框架开发,用于监听端点并处理请求。

当前Express配置如下:

const express = require('express')
const app = express()

app.use(express.raw({type: "application/json"}))
app.use(express.json())

使用express.raw是因为Stripe API需要将原始请求转换为Buffer。但这导致非Stripe接口(如获取HubSpot账户设置的/account-fetch端点)出现问题:req.body变为编码后的Buffer,仅输出数字,无法正常读取参数。

我尝试仅在Stripe端点单独配置express.raw:

app.post('/stripe/:type', express.raw({type: "application/json"}),(req, res) => {
//rest of my code
})

或完全不配置该中间件,但均无效,仍出现StripeSignatureVerificationError,无法正确验证负载签名。也曾尝试将该配置放在Stripe端点前,同样失败。

请问是否可将Buffer转回未使用express.raw时的格式,或仅为单个端点隔离使用express.raw?


解决方案

方案1:为单个Stripe端点单独配置express.raw并正确验证签名

你之前的代码存在语法错误("application/json缺少闭合引号),修正后通过调整中间件顺序,就能实现仅Stripe端点使用raw解析:

// 先全局配置JSON解析,供非Stripe路由使用
app.use(express.json());

// 单独给Stripe路由挂载raw解析中间件,确保参数完整
app.post('/stripe/:type', express.raw({ type: 'application/json' }), (req, res) => {
  const sig = req.headers['stripe-signature'];
  const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET;

  try {
    // 直接用req.body(Buffer格式)进行Stripe签名验证
    const event = stripe.webhooks.constructEvent(
      req.body,
      sig,
      webhookSecret
    );
    // 处理Stripe事件的业务逻辑
    res.json({ received: true });
  } catch (err) {
    res.status(400).send(`Webhook Error: ${err.message}`);
    return;
  }
});

// 非Stripe路由示例:HubSpot账户设置获取
app.get('/account-fetch', (req, res) => {
  // 此处req.body已自动解析为JSON格式,可直接读取参数
  res.json({ settings: /* 你的业务逻辑结果 */ });
});

核心逻辑是Express中间件按注册顺序执行,Stripe路由优先使用自身挂载的express.raw,其他路由则使用全局的express.json解析,互不干扰。

方案2:将Buffer手动转回JSON格式(适配全局raw解析场景)

如果必须全局使用express.raw,可以在非Stripe路由中手动将Buffer转换为JSON:

app.get('/account-fetch', (req, res) => {
  let requestBody;
  try {
    // 将Buffer转为UTF-8字符串后解析为JSON
    requestBody = JSON.parse(req.body.toString('utf8'));
  } catch (error) {
    return res.status(400).send('Invalid JSON payload');
  }
  // 现在可以正常使用requestBody中的参数
  res.json({ settings: requestBody.accountId });
});

这种方式需要在每个非Stripe路由中重复转换逻辑,不如方案1优雅,仅作为特殊场景的备选方案。

关键注意事项

  • 确保Stripe后台配置的webhook签名密钥与代码中webhookSecret完全一致
  • 不要在Stripe路由之前挂载任何会修改请求体的中间件(比如express.json()),否则原始Buffer会被破坏,导致签名验证失败
  • 检查请求头中是否存在stripe-signature字段,缺失会直接触发StripeSignatureVerificationError

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 23:45:41