'Keep getting " No signatures found matching the expected signature for payload." for Stripe webhook (node.js)

app.use(
    express.json({
        verify: (req, res, buf) => {
            req.rawBody = buf.toString();
        },
    }),
);

app.post('/webhook', async (req, res, next) => {
    const sig = req.headers['stripe-signature'];

    let event;

    try {
        event = stripe.webhooks.constructEvent(req.rawBody, sig, endpoint_secret);
    } catch (err) {
        return console.log(err)
    }

    if (event.type === 'invoice.payment_succeeded') {
        //...
    }

    res.send();
});

I tried following this link but I kept getting express.raw is not a function error, I also tried this:

app.use((req, res, next) => {
    if (req.originalUrl === '/webhook') {
        next();
    } else {
        express.json()(req, res, next);
    }
});

And still got the same error, would really appreciate it if I could get some help.



Solution 1:[1]

I'm using Firebase Cloud Functions as my webhook API, as so:

import webhook_app_creator from "express";
import cors from "cors";

// This example uses Express to receive webhooks
//the Cloud Function calls the webhook_app
export const webhook_app = webhook_app_creator();
// The Firebase Admin SDK to access Cloud Firestore.
//const cors = require("cors");

// Automatically allow cross-origin requests
webhook_app.use(cors({ origin: true }));

// build multiple CRUD interfaces:
webhook_app.post("/direct", async (request, response) => {
  //send the response early - the only valid response is "received"
  await commonHandler(request, response, endpointDirectSecret);
  response.json({ received: true });
});

webhook_app.post("/connect", async (request, response) => {
  //send the response early - the only valid response is "received"
  await commonHandler(request, response, endpointSecret);
  response.json({ received: true });
});

const commonHandler = async (request, response, secret) => {
  const sig = request.headers["stripe-signature"];

  try {
    request.fullEvent = stripe.webhooks.constructEvent(
      request.rawBody,
      sig,
      secret
    );
  } catch (err) {
    logger(`Webhook Error: ${err.message}`);
    return;
  }

  return queue_event(request.fullEvent);
};

The Cloud Function couldn't be simpler:

//import functions from "firebase-functions";
import { functions, webhook_app } from "../../../../services";

// Expose Express API as a single Cloud Function:
export default functions.https.onRequest(webhook_app);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 LeadDreamer