Skip to content

Instantly share code, notes, and snippets.

@soulbliss
Created June 10, 2024 13:20
Show Gist options
  • Save soulbliss/87d80361d0cd27023d646af5af7aa7ba to your computer and use it in GitHub Desktop.
Save soulbliss/87d80361d0cd27023d646af5af7aa7ba to your computer and use it in GitHub Desktop.
Code to setup stripe subscriptions. Code credits to @marc_louvion
// 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