Created
June 10, 2024 13:20
-
-
Save soulbliss/87d80361d0cd27023d646af5af7aa7ba to your computer and use it in GitHub Desktop.
Code to setup stripe subscriptions. Code credits to @marc_louvion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// app > api > webhook > stripe > js route.js --> | |
import { NextResponse } from 'next/server'; | |
import { headers } from 'next/headers'; | |
import Stripe from 'stripe'; | |
import connectMongo from '@/libs/mongoose'; | |
import User from '@models/User'; | |
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY); | |
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET; | |
export async function POST(req) { | |
await connectMongo(); | |
const body = await req.text(); | |
const signature = headers().get('stripe-signature'); | |
let data; | |
let eventType; | |
let event; | |
// verify Stripe event is legit | |
try { | |
event = stripe.webhooks.constructEvent(body, signature, webhookSecret); | |
} catch (err) { | |
console.error('Webhook signature verification failed. ${err.message}'); | |
return NextResponse.json({ error: err.message }, { status: 400 }); | |
} | |
data = event.data; | |
eventType = event.type; | |
try { | |
switch (eventType) { | |
case 'checkout.session.completed': { | |
// First payment is successful and a subscription is created (if mode was set to "subscription" in ButtonCheckout) | |
// Grant access to the product | |
const session = await stripe.checkout.sessions.retrieve( | |
data.object.id, | |
{ expand: ['line_items'] } | |
); | |
const customerId = session?.customer; | |
const customer = await stripe.customers.retrieve(customerId); | |
const priceId = session?.line_items?.data[0]?.price.id; | |
if (customer.email) { | |
user = await User.findOne({ email: customer.email }); | |
if (!user) { | |
user = await User.create({ | |
email: customer.email, | |
name: customer.name, | |
customerId | |
}); | |
} | |
await user.save(); | |
} else { | |
console.error('No user found'); | |
throw new Error('No user found'); | |
} | |
// Update user data + Grant user access to your product. It's a boolean in the database, but could be a number of credits instead | |
user.priceId = priceId; | |
user.hasAccess = true; | |
await user.save(); | |
// Extra: >>>>> send email to dash <<<< | |
break; | |
} | |
case 'customer.subscription.deleted': { | |
// Revoke access to the product | |
// The customer might have changed the plan (higher or lower plan, cancel soon etc...) | |
const subscription = await stripe.subscriptions.retrieve( | |
data.object.id | |
); | |
const user = await User.findOne({ | |
customerId: subscription.customer | |
}); | |
// Revoke access to your product | |
user.hasAccess = false; | |
await user.save(); | |
break; | |
} | |
default: | |
// Unhandled event type | |
} | |
} catch (e) { | |
console.error( | |
'stripe error: ' + e.message + ' | EVENT TYPE: ' + eventType | |
); | |
} | |
return NextResponse.json({}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment