Search code examples
javascriptstripe-paymentsremix.run

Stripe webhook nodejs remix.run Stripe webhook - No signatures found matching the expected signature for payload


Could someone help me please. Do I need to convert the request body into raw json type? I'm using remix.run to create an endpoint for the stripe webhook. I'm getting an 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 - but I don't know how to convert the req.body into raw?

import type { ActionFunction } from "@remix-run/node";
import stripe from "stripe";

export const action: ActionFunction = async ({ request }) => {
  switch (request.method) {
    case "POST": {
      const endpointSecret =
        "whsec_abxxxxaf67fxxxa955";
      console.log("Header", request.headers.get("stripe-signature"));
      const sig: any = request.headers.get("stripe-signature");
      console.log("--sig", sig);

      let event;
      try {
        event = stripe.webhooks.constructEvent(
          request.body,
          sig,
          endpointSecret
        );
        console.log("event", event);
        return null;
      } catch (err) {
        console.log("err", err);
        return null;
      }
    }
  }
  return null;
};

export default () => {
  return <p>FAILED</p>;
};

And the error that I'm getting.

{
  type: 'StripeSignatureVerificationError',
  raw: {
    message: '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'
  },
  rawType: undefined,
  code: undefined,
  doc_url: undefined,
  param: undefined,
  detail: undefined,
  headers: undefined,
  requestId: undefined,
  statusCode: undefined,
  charge: undefined,
  decline_code: undefined,
  payment_intent: undefined,
  payment_method: undefined,
  payment_method_type: undefined,
  setup_intent: undefined,
  source: undefined,
  header: 't=1669990993,v1=026c8a0xxxxxxxfc1048d1abc07,v0=85099acc2420c06bxxx22dd8553e60681befd59d238b4514cbdd',
  payload: <ref *1> ReadableStream3 [ReadableStream] 

My printed header is show the correct key, i think.

t=1669990993,v1=026c8a00b366cd657a2xxxxxxf5b003fc1048d1abc07,v0=85099acc2420c06bc0d2dxxx3e60681befd59d238b4514cbdd

Solution

  • It looks like you can get the raw request body with request.text() then use that in constructEvent.

    const payload = await request.text()
    ...
    event = stripe.webhooks.constructEvent(payload, sig, secret)
    

    You can see this here, an example shared by a Stripe Developer Advocate here.