1
votes

I'm setting up a stripe webhook to fulfill my order with stripe after a payment while hosting it with firebase functions.
When developing on a localhost everything works fine until I publish it in a firebase function where it always sends me a [400] error. Creating the payment intent works fine in the same firebase function but that one doesn't.

The error message I get is : 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

Code of my express backend :

app.post(
  "/stripe/webhook",
  bodyParser.raw({ type: "application/json" }),
  async (request, response) => {
    const payload = request.body;
    const sig = request.headers["stripe-signature"];
    let event;

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

    // Handle the checkout.session.completed event
    if (event.type === "checkout.session.completed") {
      const session = event.data.object;
      oldSession = await stripe.checkout.sessions.listLineItems(
        session.id,
        function (err, lineItems) {
          fulfillOrder(session, lineItems);
        }
      );
    }

    response.status(200);
  }
);

Anyone has an idea on how to make it work ? Thanks

2
Please edit the question to be more specific about the error. What do you see in the logs? What is the specific error message? - Doug Stevenson
I just added the error I get - pldesch
I think that would be better open an issue on stripe github page - Jan Hernandez
@JanHernandez getting the same error. Did you manage to solve it? - David Hellsing

2 Answers

1
votes

I had the same problem but managed to find a solution that worked for me. First request the rawBody in a middleware using verify:

app.use(bodyParser.json({
  verify: (req: any, res, buf, encoding) => {
    // get rawBody        
    req.rawBody = buf.toString()
  }
}))

Then parse the buffer as payload:

const payload = req.rawBody.toString()
0
votes

request.body is a pre-parsed object of the request body and should not be used for verification. Instead you likely want request.rawBody which is a Buffer of the raw request body unparsed and unmodified. Try using that instead (you may need to convert it to a string) in your constructEvent call.