import type { NextApiRequest, NextApiResponse } from 'next'; import { buffer } from 'micro'; import Stripe from 'stripe'; import { db } from '@/db/PrismaClient'; const endpointSecret = 'whsec_40011967d8d3433135936a804c21dc89a16fbba7cbb4ce1ec0f70853c5ec8000'// YOUR ENDPOINT SECRET copied from the Stripe CLI start-up earlier, should look like 'whsec_xyz123...' export const config = { api: { bodyParser: false, // don't parse body of incoming requests because we need it raw to verify signature }, }; export default async (req: NextApiRequest, res: NextApiResponse): Promise<void> => { try { const requestBuffer = await buffer(req); const sig = req.headers['stripe-signature'] as string; const stripe = new Stripe(process.env.STRIPE_SECRET_TEST_KEY, { apiVersion: '2022-11-15' }) let event; try { // Use the Stripe SDK and request info to verify this Webhook request actually came from Stripe event = stripe.webhooks.constructEvent( requestBuffer.toString(), // Stringify the request for the Stripe library sig, endpointSecret ); } catch (err: any) { console.log(`⚠️ Webhook signature verification failed.`, err.message); return res.status(400).send(`Webhook signature verification failed.`); } let subscription = event.data.object as Stripe.Subscription; // Handle the event switch (event.type) { // Handle successful subscription creation case 'customer.subscription.updated': try { await db.user.update({ // Find the customer in our database with the Stripe customer ID linked to this purchase where: { stripeCustomerId: subscription.customer as string }, // Update that customer so their status is now active data: { isSubscribed: subscription.status === 'active', interval: subscription.items.data[0].plan.interval, } }) break; } catch (error) { console.error('ERROR update subscription', error) break; } case "customer.subscription.deleted": await db.user.update({ // Find the customer in our database with the Stripe customer ID linked to this purchase where: { stripeCustomerId: subscription.customer as string }, // Update that customer so their status is now active data: { isSubscribed: false, interval: null, } }) break; // ... handle other event types default: console.log(`Unhandled event type ${event.type}`); } // Return a 200 response to acknowledge receipt of the event res.status(200).json({ received: true }); } catch (err) { // Return a 500 error console.log(err); res.status(500).end(); } };