javascript 39 lines · 7 steps

Handling Stripe webhooks in Next.js

A Next.js route handler that verifies Stripe webhook signatures and dispatches on event type.

Explained by highlit
1import { NextResponse } from 'next/server';
2import Stripe from 'stripe';
3import { headers } from 'next/headers';
4 
5const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
6 
7export async function POST(request) {
8 const body = await request.text();
9 const signature = (await headers()).get('stripe-signature');
10 
11 let event;
12 try {
13 event = stripe.webhooks.constructEvent(
14 body,
15 signature,
16 process.env.STRIPE_WEBHOOK_SECRET
17 );
18 } catch (err) {
19 console.error(`Webhook signature verification failed: ${err.message}`);
20 return NextResponse.json({ error: 'Invalid signature' }, { status: 400 });
21 }
22 
23 switch (event.type) {
24 case 'checkout.session.completed': {
25 const session = event.data.object;
26 await fulfillOrder(session.client_reference_id, session.payment_intent);
27 break;
28 }
29 case 'invoice.payment_failed': {
30 const invoice = event.data.object;
31 await flagPastDue(invoice.customer);
32 break;
33 }
34 default:
35 console.log(`Unhandled event type: ${event.type}`);
36 }
37 
38 return NextResponse.json({ received: true });
39}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Always verify webhook signatures against the raw request body before trusting any payload.
  2. 2Webhook endpoints should switch on event type and acknowledge with 200 once accepted.
  3. 3Read the body as raw text, not JSON, so the signature check sees the exact bytes Stripe signed.

Related explainers

Share this explainer

Here's the card — post it anywhere.

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