Spoeken
Spoeken

Reputation: 2598

How to check Stripe webhook signatures in firebase functions

Hi 👋đŸģI'm trying to verify a Stripe signature in Firebase functions. But when i try stripe.webhooks.constructEvent it catches an error saying:

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 😔

I've logged out the raw body, and it looks fine 🤖

<Buffer 7b 0a 20 20 22 69 64 22 3a 20 22 65 76 74 5f 31 46 72 6b 4d 73 41 55 73 34 77 79 52 42 49 73 63 6d 66 72 43 39 7a 37 22 2c 0a 20 20 22 6f 62 6a 65 63 ... >

Here is the relevant code:

  // A webhook called by stripe
  const sig = req.headers['stripe-signature']
  let event
  // 1. construct event and validate
  try {
    event = stripe.webhooks.constructEvent(req.rawBody, sig, functions.config().stripe.mytestkey)
    assert(event)
  } catch (err) {
    console.log(`Error when constructing Stripe event: ${err} - ${req.body}`)
    res.status(400).send({ error: `Stripe webhook error: ${err}` })
    return
  }

  // 2. Handle webhook
  res.status(200).send(`successfully handled webhook ${hook}`)
})

Any thoughts? 💭

Upvotes: 2

Views: 1417

Answers (3)

Kyle Smith
Kyle Smith

Reputation: 46

Same error for me but different problem:

The secret I passed into the constructEvent function was incorrect.

I entered: The Stripe account secret key;
It expected: A secret key generated by that webhook.

To get the webhook secret key:

For local listeners (development): Scroll to where you typed stripe listen in the terminal, you may find: Your webhook signing secret is <THIS>

For hosted endpoints (production): Click on the webhook on the Stripe dashboard, under "Signing secret" it is there.

Upvotes: 0

Spoeken
Spoeken

Reputation: 2598

Finally, I figured out I had to write req.rawBody.toString('utf8'). Source: https://github.com/stripe/stripe-node/issues/341

Upvotes: 3

Renaud Tarnec
Renaud Tarnec

Reputation: 83181

Doing

let sig = req.get('stripe-signature');

instead of

const sig = req.headers['stripe-signature']

should do the trick.

According to the Express documentation:

req.get(field)

Returns the specified HTTP request header field (case-insensitive match).

Upvotes: 3

Related Questions