#orangesidny_webhooks-signature

1 messages ยท Page 1 of 1 (latest)

strong horizonBOT
#

๐Ÿ‘‹ Welcome to your new thread!

โฒ๏ธ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

โฑ๏ธ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

๐Ÿ”— This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1234544425531609188

๐Ÿ“ Have more to share? Add more details, code, screenshots, videos, etc. below.

vestal garnetBOT
tiny burrow
#

HI ๐Ÿ‘‹

Verifying Stripe webhooks with Node.JS and Express are especially difficult due to how Express handles incoming requests.

lilac glen
#

The thing is it used to work and I got it working on the production server but I have not changed anything and all of a sudden it stopped verifying the webhooks

lilac glen
tiny burrow
#

What does "did not really seem to help" mean? Did you implement any of the solutions? Did they change the behavior you are seeing?

lilac glen
#

I have removed
express.json() for the webhook endpoint

I have added bodyParser.raw({type: 'application/json'})

lilac glen
#

This is the error
No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?

tiny burrow
#

What happens when you chage the type to bodyParser.raw({type: '*/*'})

lilac glen
#

if I make the payload to be req.body this is the error

Webhook payload must be provided as a string or a Buffer (https://nodejs.org/api/buffer.html) instance representing the _raw_ request body.Payload was provided as a parsed JavaScript object instead.
Signature verification is impossible without access to the original signed material.

Where the payload is json object with id, object. api_version...

But if I make the payload = req.body.toString()
This is the error

No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe?

Where payload is [object Object]

#

This is the start of the code, which is erroring in the try-catch statement

    let event;
    let payload = req.body
    let endpointSecret = config.webhook_test
    let sig_header = req.headers['stripe-signature']
    const signature = sig_header

    console.log("PAYLOAD", payload)
    console.log("SIGNATURE", signature)
    console.log("SECRET", endpointSecret)

    try{
        event =  stripeInstance.webhooks.constructEvent(
            payload, signature, endpointSecret
        )
    } catch (error){
        console.log(error.message)
        return res.sendStatus(400);
    }
tiny burrow
#

Did you change the bodyParser to use */*?

#

app.use(bodyParser.raw({ type: '*/*' }))

lilac glen
#
if (req.originalUrl === '/premium/paymentmade' || req.originalUrl === '/api/premium/paymentmade') {
      "Webhook called"
            app.use(bodyParser.raw({ type: '*/*' }))
            next(); // Do nothing with the body because I need it in a raw state.
    } 
router.post(
  "/paymentmade",
  bodyParser.raw({type: '*/*'}),
  createSession.paymentMade
);

I tried both versions and one of them worked

tiny burrow
#

I tried both versions and one of them worked

  1. Which one?
  2. And it doesn't work now?
lilac glen
#

If I make the body a string a different error, if I don't a different error occurs

lilac glen
tiny burrow
#

Is this just a Node.js + Express integration? No other frameworks?

Does this run locally? Is the issue only in production?

lilac glen
#

Currently, it is only the backend (Node js and express)
I am using the Stripe CLI to test but I have already created the working frontend store so I can also test with a online store.

The current issue is testing locally, with the webhooks, I can create checkout sessions which works,

But it is just authenticating webhooks that does not work

tiny burrow
#

You said that it was working earlier, is that correct?

lilac glen
tiny burrow
#

Can you diff your local and see what has changed?

vestal garnetBOT
lilac glen
lilac glen
vast yarrow
#

orangesidny_webhooks-signature

lilac glen
#

I also made sure the express.json was not called as well

vast yarrow
#

The problem seems to be with your environment really right now. You need to make sure that you get the raw payload we send you in the post body. The error is here when you pass something else

lilac glen
#

should the payload be a json object or rather a string

#

Because currently the payload is a json object

vast yarrow
#

It show be a raw string, definitely not a JSON object.

lilac glen
#

This is a copy of the payload, I am not sure what is sensitive so I removed the ids,

{
  id: '',
  object: 'event',
  api_version: '2022-11-15',
  created: 1714411448,
  data: {
    object: {
      id: '',
      object: 'payment_intent',
      amount: 2000,
      amount_capturable: 0,
      amount_details: [Object],
      amount_received: 0,
      application: null,
      application_fee_amount: null,
      automatic_payment_methods: null,
      canceled_at: null,
      cancellation_reason: null,
      capture_method: 'automatic',
      client_secret: '',
      confirmation_method: 'automatic',
      created: 1714411448,
      currency: 'usd',
      customer: null,
      description: '(created by Stripe CLI)',
      invoice: null,
      last_payment_error: null,
      latest_charge: null,
      livemode: false,
      metadata: {},
      next_action: null,
      on_behalf_of: null,
      payment_method: null,
      payment_method_configuration_details: null,
      payment_method_options: [Object],
      payment_method_types: [Array],
      processing: null,
      receipt_email: null,
      review: null,
      setup_future_usage: null,
      shipping: [Object],
      source: null,
      statement_descriptor: null,
      statement_descriptor_suffix: null,
      status: 'requires_payment_method',
      transfer_data: null,
      transfer_group: null
    }
  },
  livemode: false,
  pending_webhooks: 2,
  request: {
    id: 'req_',
    idempotency_key: ''
  },
  type: 'payment_intent.created'
}
vast yarrow
#

If you get a JSON object it's because something in your code/environment is parsing the data and giving you a JSON object when we want the exact raw payload you got in the request

lilac glen
#

is there anyway to check what does that, or convert it to raw afterwards

vast yarrow
#

no you absolutely can't convert it to raw afterwards because doing that changes the payload. The signature verification only works on the exact original raw payload we sent you, up to the exact same order of properties, spaces, commas, etc.