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

Stripe Webhook签名验证失败:未提供负载,如何解决?

问题

我正尝试在应用中集成Stripe API,但接收Webhook数据时遇到错误。完成成功收费后,代码返回如下错误提示:

router.post('/webhook', async (req, res) => {

    console.log("Received request");

    let data;
    let eventType;
    // Check if webhook signing is configured.
    const webhookSecret = stripeWebhookSigningKey;

    if (webhookSecret) {
        // Retrieve the event by verifying the signature using the raw body and secret.
        let event;
        let signature = req.headers['stripe-signature'];

        try {
            event = stripe.webhooks.constructEvent(
                req['rawBody'],
                signature,
                webhookSecret
            );
        } catch (err) {
            console.log(`⚠️  Webhook signature verification failed: ` + err);
            return res.sendStatus(400);
        }
        // Extract the object from the event.
        data = event.data;
        eventType = event.type;
    } else {
        // Webhook signing is recommended, but if the secret is not configured in `config.js`,
        // retrieve the event data directly from the request body.
        data = req.body.data;
        eventType = req.body.type;
    }

    switch (eventType) {
        case 'checkout.session.completed':
            console.log(data);
            break;
        case 'invoice.paid':
            console.log(data);
            break;
        case 'invoice.payment_failed':
            console.log(data);    
            break;
        default:
            // Unhandled event type
            console.log(data);    
            break;
    }

    res.sendStatus(200);
});

⚠️ Webhook signature verification failed: Error: No webhook payload was provided.

有用户反馈该问题源于响应JSON格式错误,我已在脚本顶部添加如下代码修复,但仍无效果:

router.use(
    express.json({
        verify: (req, res, buffer) => (req['rawBody'] = buffer),
    })
);

Stripe CLI工具明确已发送请求,但日志显示HTTP 400状态。请问问题出在哪里,该如何解决?

可能的原因及解决方法

1. 中间件加载顺序错误

确保配置的express.json()中间件在webhook路由定义之前加载。如果中间件在路由之后执行,req.rawBody不会被提前设置,导致constructEvent无法获取原始请求 payload。

正确顺序示例:

// 先加载带verify的json中间件
router.use(
    express.json({
        verify: (req, res, buffer) => (req['rawBody'] = buffer),
    })
);

// 再定义webhook路由
router.post('/webhook', async (req, res) => {
    // 你的路由逻辑
});

2. 其他中间件提前解析了请求体

如果应用中存在其他解析请求体的中间件(比如express.urlencoded()或第三方中间件),它们可能会先于你配置的express.json()处理请求,导致原始buffer丢失。

解决方式:只为webhook路由单独配置带verify的json中间件,避免全局中间件干扰:

// 直接在webhook路由中挂载专属中间件
router.post('/webhook', 
    express.json({
        verify: (req, res, buffer) => (req['rawBody'] = buffer),
    }),
    async (req, res) => {
        // 你的路由逻辑
    }
);

3. 签名密钥配置错误

确认stripeWebhookSigningKey使用的是Stripe Dashboard中对应webhook端点的签名密钥(以whsec_开头),而非普通API密钥。密钥不匹配会直接导致签名验证失败,触发类似报错。

4. Stripe CLI 转发路径不匹配

检查Stripe CLI的转发命令是否指向正确的路由路径。例如你的路由是/webhook,确保CLI命令为:

stripe listen --forward-to localhost:3000/webhook

5. 验证req.rawBody是否正确设置

在constructEvent执行前添加日志,确认req.rawBody和签名头是否存在:

console.log('Raw body exists:', !!req.rawBody);
console.log('Stripe signature:', req.headers['stripe-signature']);

如果req.rawBody为undefined,说明中间件的verify函数未正确执行,需要重新排查中间件配置逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:35:21