NilsKyuubi
NilsKyuubi

Reputation: 371

Stripe Webhooks StripeSignatureVerificationError

I'm currently testing the Stripe Webhook Endpoints for the Checkout Process.

I'm confused because Stripe shows two different snippets how to set up the Webhook endpoint in their docs.

In the Checkout Doc they show this code snippet:

const stripe = require('stripe')('sk_test_...');

// Find your endpoint's secret in your Dashboard's webhook settings
const endpointSecret = 'whsec_...';

// Using Express
const app = require('express')();

// Use body-parser to retrieve the raw body as a buffer
const bodyParser = require('body-parser');

// Match the raw body to content type application/json
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => {
  const sig = request.headers['stripe-signature'];

  let event;

  try {
    event = stripe.webhooks.constructEvent(request.body, 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;

    // Fulfill the purchase...
    handleCheckoutSession(session);
  }

  // Return a response to acknowledge receipt of the event
  response.json({received: true});
});

app.listen(8000, () => console.log('Running on port 8000'));

And in their Webhook Docs they are showing this snippet:

const app = require('express')();
// Use body-parser to retrieve the raw body as a buffer
const bodyParser = require('body-parser');

// Match the raw body to content type application/json
app.post('/webhook', bodyParser.raw({type: 'application/json'}), (request, response) => {
  let event;

  try {
    event = JSON.parse(request.body);
  } catch (err) {
    response.status(400).send(`Webhook Error: ${err.message}`);
  }

  // Handle the event
  switch (event.type) {
    case 'payment_intent.succeeded':
      const paymentIntent = event.data.object;
      // Then define and call a method to handle the successful payment intent.
      // handlePaymentIntentSucceeded(paymentIntent);
      break;
    case 'payment_method.attached':
      const paymentMethod = event.data.object;
      // Then define and call a method to handle the successful attachment of a PaymentMethod.
      // handlePaymentMethodAttached(paymentMethod);
      break;
    // ... handle other event types
    default:
      // Unexpected event type
      return response.status(400).end();
  }
  // Return a response to acknowledge receipt of the event
  response.json({received: true});
});

app.listen(8000, () => console.log('Running on port 8000'));

I tried both snippets but nothing seems to work for me.

The first one gives me the StripeSignatureVerificationError when I try to constructEvent(...)

and the second one is telling me that the Object event is undefined.

Does someone know why both of these endpoints are not working for me ?

Upvotes: 1

Views: 5881

Answers (2)

Faizan Ali
Faizan Ali

Reputation: 1

const sig = request.headers['stripe-signature'];
const event = stripe.webhooks.constructEvent(req.rawBody, sig, endpointSecret`);

When I made these changes in my code, I successfully resolved the issue.

const payload = req.body;
      const payloadString = JSON.stringify(payload, null, 2);
      const secret = endpointSecret;
      const header = stripe.webhooks.generateTestHeaderString({
        payload: payloadString,
        secret,
  });


 const event = stripe.webhooks.constructEvent(payloadString, header, secret);

Upvotes: 0

Black_Rider
Black_Rider

Reputation: 1575

Before using JSON Body parser configure to receive RAW body

app.use(bodyParser.raw({type: "*/*"}))  <-- This line need to be added
app.use(bodyParser.json())

More discussion https://github.com/stripe/stripe-node/issues/331

Upvotes: 5

Related Questions