javascript 42 lines · 7 steps

Verifying Stripe webhooks in Express

An Express route that authenticates incoming Stripe events with a signature check before acting on them.

Explained by highlit
1const express = require('express');
2const Stripe = require('stripe');
3 
4const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
5const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
6 
7const router = express.Router();
8 
9router.post(
10 '/webhooks/stripe',
11 express.raw({ type: 'application/json' }),
12 async (req, res) => {
13 const signature = req.headers['stripe-signature'];
14 
15 let event;
16 try {
17 event = stripe.webhooks.constructEvent(req.body, signature, endpointSecret);
18 } catch (err) {
19 console.error(`Webhook signature verification failed: ${err.message}`);
20 return res.status(400).send(`Webhook Error: ${err.message}`);
21 }
22 
23 switch (event.type) {
24 case 'checkout.session.completed': {
25 const session = event.data.object;
26 await fulfillOrder(session);
27 break;
28 }
29 case 'invoice.payment_failed': {
30 const invoice = event.data.object;
31 await notifyPaymentFailure(invoice.customer);
32 break;
33 }
34 default:
35 console.log(`Unhandled event type: ${event.type}`);
36 }
37 
38 res.json({ received: true });
39 }
40);
41 
42module.exports = router;
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Webhook endpoints must verify a cryptographic signature so attackers can't forge events.
  2. 2Signature verification needs the unparsed raw body, so the usual JSON parser must be bypassed for this route.
  3. 3Acknowledge the webhook with a 2xx quickly and branch on event type to run the right side effect.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Verifying Stripe webhooks in Express — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code