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

使用Bun + Hono处理Stripe Webhook签名时解析事件失败求助

解决Bun+Hono环境下Stripe Webhook签名验证失败问题

核心问题排查与修复方案

1. 错误适配Cloudflare专属Crypto Provider

你当前代码中使用的Stripe.createSubtleCryptoProvider()是Cloudflare Worker环境的专属适配,而Bun本身内置标准Web Crypto API,无需额外指定该Provider。移除这个参数即可让Stripe SDK自动适配Bun环境:

修改constructStripeEvent函数:

async function constructStripeEvent(body: string, sig: string) {
    try {
        let event = await stripe.webhooks.constructEventAsync(
            body,
            sig,
            config.stripe.webhookSecret
            // 移除最后两个参数:undefined和Stripe.createSubtleCryptoProvider()
        );
        return event;
    } catch (error) {
        log.error(error);
        return { error };
    }
}

2. 确保请求体完整性

Stripe签名验证要求原始请求体字节完全一致,若Hono中间件提前解析或修改了请求体编码,会直接导致验证失败:

  • 检查全局/路由组是否启用bodyParser之类的中间件,webhook路由需跳过这类处理
  • 保持await c.req.text()的写法,同时将body的类型从any改为string,避免类型隐式转换问题

3. 验证Webhook密钥正确性

确认config.stripe.webhookSecret是Stripe Dashboard对应Webhook端点的签名密钥(格式为whsec_xxx开头),而非普通API密钥,密钥不匹配是签名失败的常见原因。

4. 本地测试的转发一致性

若使用ngrok等工具本地开发,需保证Stripe Dashboard配置的Webhook URL与转发地址完全一致;测试事件必须从Stripe Dashboard发送,手动构造的请求体易出现编码差异导致验证失败。

修复后完整代码示例

// POST /stripe/webhook
stripe.post("/webhook", async (c) => {
    const body = await c.req.text();
    const sig = c.req.raw.headers.get("stripe-signature");

    if (!sig) {
        return c.json({ error: "No signature" }, 401);
    }

    const event = await constructStripeEvent(body, sig);

    if (event.error) {
        c.status(400);
        return c.json({ error: "Invalid signature", detail: event.error.message });
    }

    log.info({ event });

    return c.json({ message: "ok" });
});

// construct wh event
async function constructStripeEvent(body: string, sig: string) {
    try {
        const event = await stripe.webhooks.constructEventAsync(
            body,
            sig,
            config.stripe.webhookSecret
        );
        return { event }; // 统一成功/失败返回结构,便于后续判断
    } catch (error) {
        log.error("Webhook签名验证失败:", error);
        return { error: error as Error };
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 19:16:02