Webhooks allow us to subscribe to particular events, and have Stripe let us know when they occur. From the Stripe dashboard we can specify an endpoint to call, and which events we care about. For subscriptions, we want to know when a new subscription occurs, is updated, or deleted.
In this video, we create a new API route to handle webhook events from Stripe. We can call the stripe.webhooks.constructEvent
function which returns the event object. It also takes the req
, signature
and signingSecret
to verify the request is valid and came from Stripe.
The signature
can be extracted from the request's headers, and the signing secret is available in the Stripe dashboard, however, the Next.js req
object is a different structure to what constructEvent
is expecting. Therefore, we need to install the micro
package and use its buffer
function to get the reqBuffer
. We also need to export a config object from our page component, setting bodyParser
to false
.
Instructor: [0:00] Our customer now has an active subscription, but this information is not reflected in our database. We can use Stripe Webhooks to get notified anytime these subscription events occur. Let's start by enabling Webhooks in our Stripe developer settings. This option is under Webhooks. We can scroll down to say Add an Endpoint.
[0:18] We could use Stripe's CLI to test in a local environment, but since we have ngrok already set up to give us a public URL available to the Internet, we can just use that. Let's start our ngrok server again and forward our HTTP traffic to port 3000. We can then copy this HTTPS URL and paste it here.
[0:41] We want to go to that URL/api/stripe-hooks. We then need to tell Stripe which events we actually care about, and in the case of subscriptions, this will be under Customer. Let's scroll down to find customer.subscription. We want to listen to the created, deleted, and also the updated events.
[1:01] Let's click Add Events and then Add Endpoint. We can now create our new API route to handle those Stripe Webhook events. Let's create our handler function. We can check Stripe is successfully calling this endpoint by console logging out event received.
[1:18] Then sending back a response received set to true. We can trigger this by going through our subscribe flow. If we open up our console, we should see that we've received some events. Let's work out what those events were.
[1:32] Let's start by importing our initStripe function and then creating our Stripe client. We can then get our event information by calling Stripe.Webhooks.constructevent. This will take our request, our signature, and our signing secret.
[1:49] We can get our signature from request.headers and then pulling out the stripe-signature. We can get our signing secret from our Stripe dashboard. Again, under evelopers, Webhooks, and then our specific Webhook.
[2:01] We can click Reveal under Signing Secret and copy this value into our .env file. We'll need to restart our next server to read that new value in. We can grab that value from process.mf.stripe_signing_secret. This function will also validate that this request is actually coming from Stripe.
[2:22] Let's wrap this in a try-catch, in case that's not the case. If we have an error, let's console log that out. Then let's send back a response with the status code 400 and the message Webhook error, with that error.message. This function will also give us back our event.
[2:38] Let's declare that outside our try-catch block and set that to whatever we get back. We can then console log out our event. Now when trigger our Subscription event and open up the Console, we see a Stripe signature verification error. That's because the shape of our request object that we get within our Next.js API route is not the shape that Stripe is expecting it to be.
[3:01] If we'd like it to be in that shape, we need to install the Micro package. We then want to import buffer from Micro and then get our request buffer by calling buffer and passing it our request.
[3:15] We can then pass this along to the constructEvent function and export a config object with the key API set to another object with the key body parser set to false.
[3:26] When we trigger our Webhook and open up the Console, we see our event objects for customer subscription created and customer subscription updated.
Excellent resource! Thanks! 🙌
Note for others who are new to Next.js: the bodyParser thing is part of Next.js; docs here: https://nextjs.org/docs/api-routes/api-middlewares#custom-config