Stripe webhook body signature processing (Bun + Hono)

120 Views Asked by At

I am having some difficulty parsing events from my Stripe webhook. I found this example on GH (https://github.com/stripe-samples/stripe-node-cloudflare-worker-template/blob/main/src/index.js) and followed how they implemented it. Still no luck. (Using Bun and Hono)

Here's my code

// 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: any = await constructStripeEvent(body, sig);

    if (event === null || event.error) {
        c.status(400);
        return c.json({ error: "Invalid signature" });
    }

    log.info({ event });

    return c.json({ message: "ok" });
});
// construct wh event
async function constructStripeEvent(body: any, 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 };
    }
}

This produces this error enter image description here

Let me know if I'm missing anything here. Thanks!

1

There are 1 best solutions below

0
On

The signature that is sent with an Event to your webhook endpoint is calculated based on a specific raw payload that Stripe generates. If you (or your environment/framework) changes anything on that payload, the signature won't match. You have to make sure that your code reads the exact raw payload/body that Stripe sent you in its request. With Node.js and similar environments, it's really common that something tries to help and detect the payload is JSON and parses it for you. If you look at the error message stripe-node returns here, it's warning you that you don't seem to have given it the raw payload. So what you need to figure out is what is getting in the way and how to get the exact same raw payload so that the signature verification can work. A common mistake is changing line returns in the payload or orders of properties. On stripe-node's Github repo there's this issue that lists numerous potential solutions that worked for some people and might work for you.