Webhook, RawBody and Stripe

Hi,

I’m following the tutorial about Stripe and Netlify (https://www.netlify.com/blog/2020/04/13/learn-how-to-accept-money-on-jamstack-sites-in-38-minutes/), all works very well but the last part about webhooks is not so clear. I have some trouble with ‘body’ and Stripe signature. Reading the docs I need to pass the ‘rawBody’ and not the ‘body’. Any ideas?

hey, @Lorenzo!

Thor and I ended up moving the webhooks setup to its own post, which you can read here: https://www.netlify.com/blog/2020/04/22/automate-order-fulfillment-w/stripe-webhooks-netlify-functions/

let me know if that clears up your questions. if not, I’m here to help!

2 Likes

[UPDATE]
Sorry Jason, I’m near to the solution, first of all I miss the step to insert the right Webhook secret key (the local one) in Netlify. I let you know… thanks

Hi Jason,

first of all thanks for all your videos on Gatsby and tutorial like the one I’m following.
I’m not a professional developer so I sure miss something.

I’ve implemented your webhook solution both on firebase functions and netlify with two different Stripe Webhooks (and of course two differente endpoint). With Firebase I can test everything without any errors. This is an extract of the functions, based on your code, deployed on firebase. Here, I can take the request and the rawBody:

    export const handlePurchase = functions.https.onRequest( (req, res) => {
        const sig = req.headers["stripe-signature"] as string;
        let event;
        try {
            event = stripe.webhooks.constructEvent(req.rawBody, sig, endpointSecret);
            if (event.type === 'checkout.session.completed') {
                const eventObject = event.data.object;
    ...

with Netlify I’ve a problem both in local and in live version (I set all my keys in ENV and for local env I use stripe and netlify client for run both server and the webhook listener).

I can’t test the endpoint from Stripe, and in local I get this error, in “ntl dev terminal”:

Request from ::1: POST /.netlify/functions/handle-purchase
Stripe webhook failed with Error: No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? https://github.com/stripe/stripe-node#webhook-signing
Response with status 400 in 11 ms.

and in the terminal with stripe listen I got:

2020-05-27 19:11:07  <--  [400] POST http://localhost:8888/.netlify/functions/handle-purchase [evt_1GnSmTL1itY7e9WJytWrD7jm]

This is the full code of handle-purchase.js:

const stripe = require('stripe')('process.env.STRIPE_SECRET_KEY');

exports.handler = async ({ body, headers }) => {
  try {
    const stripeEvent = stripe.webhooks.constructEvent(
      body,
      headers['stripe-signature'],
      process.env.STRIPE_WEBHOOK_SECRET
    );

    if (stripeEvent.type === 'checkout.session.completed') {
      const eventObject = stripeEvent.data.object;
      const items = JSON.parse(eventObject.metadata.items);
      const shippingDetails = eventObject.shipping;

      const purchase = { items, shippingDetails };
      console.log(`📦 Fulfill purchase:`, JSON.stringify(purchase, null, 2));
    }

    return {
      statusCode: 200,
      body: JSON.stringify({ received: true }),
    };
  } catch (err) {
    console.log(`Stripe webhook failed with ${err}`);

    return {
      statusCode: 400,
      body: `Webhook Error: ${err.message}`,
    };
  }
};

Maybe I miss something for Netlify. Thanks for your comprehension about my poor English.

Lorenzo

hey there! it looks like the local Stripe webhook secret doesn’t match what’s coming in from the webhook

when you told the Stripe CLI to listen, do you update your env vars in Netlify to use the value it gave back as STRIPE_WEBHOOK_SECRET?

if yes, can you please share the content of body and headers for a test webhook so we can see what’s coming back?

thanks!