From 8fa34a5fe38ff359229dedab7520b4ee87a4d798 Mon Sep 17 00:00:00 2001 From: Chris Streeter <60793455+streeter-stripe@users.noreply.github.com> Date: Tue, 7 Jan 2025 11:49:56 -0500 Subject: [PATCH] Add the start of a webhook handler (#210) * Add the start of a webhook handler * fix handler * Apply suggestions from code review Co-authored-by: Jorge Aguirre Gonzalez <95381655+jorgea-stripe@users.noreply.github.com> Signed-off-by: Chris Streeter <60793455+streeter-stripe@users.noreply.github.com> --------- Signed-off-by: Chris Streeter <60793455+streeter-stripe@users.noreply.github.com> Co-authored-by: Jorge Aguirre Gonzalez <95381655+jorgea-stripe@users.noreply.github.com> --- .env.example | 1 + README.md | 12 ++++++++++ app/api/webhooks/route.ts | 48 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 app/api/webhooks/route.ts diff --git a/.env.example b/.env.example index 88180e53..0d892569 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,7 @@ # Get your Stripe keys from https://stripe.com/docs/keys STRIPE_SECRET_KEY="sk_INSERT_YOUR_SECRET_KEY" STRIPE_PUBLIC_KEY="pk_INSERT_YOUR_PUBLISHABLE_KEY" +STRIPE_WEBHOOK_SECRET="whsec_INSERT_YOUR_WEBHOOK_SECRET" NEXT_PUBLIC_STRIPE_PUBLIC_KEY=$STRIPE_PUBLIC_KEY diff --git a/README.md b/README.md index a7aebcb6..0207c720 100644 --- a/README.md +++ b/README.md @@ -86,3 +86,15 @@ yarn dev ``` Go to `http://localhost:{process.env.PORT}` in your browser to start using the app. + +To test events sent to your event handler, you can run this command in a separate terminal: + +``` +stripe listen --forward-to localhost:3000/api/webhooks +``` + +Then, trigger a test event with: + +``` +stripe trigger payment_intent.succeeded +``` diff --git a/app/api/webhooks/route.ts b/app/api/webhooks/route.ts new file mode 100644 index 00000000..3919e6f8 --- /dev/null +++ b/app/api/webhooks/route.ts @@ -0,0 +1,48 @@ +import {type NextRequest} from 'next/server'; +import {NextResponse} from 'next/server'; +import {stripe} from '@/lib/stripe'; + +export async function POST(req: NextRequest) { + const body = await req.text(); + + const sig = req.headers.get('stripe-signature'); + if (!sig) { + return NextResponse.json( + {error: 'Cannot find the webhook signature'}, + {status: 400} + ); + } + + const secret = process.env.STRIPE_WEBHOOK_SECRET; + if (!secret) { + return NextResponse.json( + {error: 'Cannot find the webhook secret'}, + {status: 400} + ); + } + + let event; + try { + event = stripe.webhooks.constructEvent( + body, + sig, + process.env.STRIPE_WEBHOOK_SECRET || '' + ); + } catch (err: any) { + return NextResponse.json( + {error: `Webhook Error: ${err.message}`}, + {status: 400} + ); + } + + // Handle events - see full event list: https://docs.stripe.com/api/events/types + switch (event.type) { + case 'account.updated': + break; + default: + console.log('Unhandled event type', event.type); + break; + } + + return NextResponse.json({}); +}