Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the RAW Body using serverless functions?

I am migrating from Express to serverless functions on Zeit Now.

The Stripe webhook docs asks for a raw body request, When using Express I could get it via bodyParser, but how does it work on serverless functions? How can I receive the body in a string format in order to validate the stripe signature?

The support team redirected me to this documentation link, I'm confused, as I understand, I have to pass text/plain into the request header, but I don't have control over it since Stripe is the one sending the webhook.

export default async (req, res) => {
    let sig = req.headers["stripe-signature"];
    let rawBody = req.body;
    let event = stripe.webhooks.constructEvent(rawBody, sig, process.env.STRIPE_SIGNING_SECRET);
    ...
}

In my function, I'm receiving req.body as an object, how can I fix this issue?

like image 507
Hiroyuki Nuri Avatar asked Jan 02 '20 15:01

Hiroyuki Nuri


1 Answers

The following code snippet worked for me (modified from this source):

const endpointSecret = process.env.STRIPE_SIGNING_SECRET;

export default async (req, res) => {
  const sig = req.headers['stripe-signature'];
  let event;
  let bodyChunks = [];

  req
    .on('data', chunk => bodyChunks.push(chunk))
    .on('end', async () => {
      const rawBody = Buffer.concat(bodyChunks).toString('utf8');

      try {
        event = stripe.webhooks.constructEvent(rawBody, sig, endpointSecret);
      } catch (err) {
        return res.status(400).send(`Webhook Error: ${err.message}`);
      }

      // Handle event here
      ...

      // Return a response to acknowledge receipt of the event
      res.json({ received: true });
    });
};

export const config = {
  api: {
    bodyParser: false,
  },
};
like image 165
Richard Chu Avatar answered Sep 27 '22 22:09

Richard Chu