Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit 4f5b603

Browse files
Merge pull request #2 from chriscarrollsmith/issue170
Issue170
2 parents c7867b2 + 1506472 commit 4f5b603

File tree

3 files changed

+46
-6
lines changed

3 files changed

+46
-6
lines changed

app/api/webhooks/route.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@ import { stripe } from '@/utils/stripe';
33
import {
44
upsertProductRecord,
55
upsertPriceRecord,
6+
deleteProductRecord,
7+
deletePriceRecord,
68
manageSubscriptionStatusChange
79
} from '@/utils/supabase-admin';
810

911
const relevantEvents = new Set([
1012
'product.created',
1113
'product.updated',
14+
'product.deleted',
1215
'price.created',
1316
'price.updated',
17+
'price.deleted',
1418
'checkout.session.completed',
1519
'customer.subscription.created',
1620
'customer.subscription.updated',
@@ -24,8 +28,9 @@ export async function POST(req: Request) {
2428
let event: Stripe.Event;
2529

2630
try {
27-
if (!sig || !webhookSecret) return;
31+
if (!sig || !webhookSecret) throw new Error("Missing Stripe Signature or Webhook Secret!");
2832
event = stripe.webhooks.constructEvent(body, sig, webhookSecret);
33+
console.log(`🔔 Webhook received: ${event.type}`);
2934
} catch (err: any) {
3035
console.log(`❌ Error message: ${err.message}`);
3136
return new Response(`Webhook Error: ${err.message}`, { status: 400 });
@@ -42,6 +47,12 @@ export async function POST(req: Request) {
4247
case 'price.updated':
4348
await upsertPriceRecord(event.data.object as Stripe.Price);
4449
break;
50+
case 'product.deleted':
51+
await deleteProductRecord(event.data.object as Stripe.Product);
52+
break;
53+
case 'price.deleted':
54+
await deletePriceRecord(event.data.object as Stripe.Price);
55+
break;
4556
case 'customer.subscription.created':
4657
case 'customer.subscription.updated':
4758
case 'customer.subscription.deleted':

utils/helpers.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,23 @@ import { Database } from '@/types_db';
33
type Price = Database['public']['Tables']['prices']['Row'];
44

55
export const getURL = () => {
6-
let url =
7-
process?.env?.NEXT_PUBLIC_SITE_URL ?? // Set this to your site URL in production env.
8-
process?.env?.NEXT_PUBLIC_VERCEL_URL ?? // Automatically set by Vercel.
6+
// Check if NEXT_PUBLIC_SITE_URL is set and non-empty. Set this to your site URL in production env.
7+
let url = process?.env?.NEXT_PUBLIC_SITE_URL && process.env.NEXT_PUBLIC_SITE_URL.trim() !== ''
8+
? process.env.NEXT_PUBLIC_SITE_URL
9+
: // If not set, check for NEXT_PUBLIC_VERCEL_URL, which is automatically set by Vercel.
10+
process?.env?.NEXT_PUBLIC_VERCEL_URL && process.env.NEXT_PUBLIC_VERCEL_URL.trim() !== ''
11+
? process.env.NEXT_PUBLIC_VERCEL_URL
12+
: // If neither is set, default to localhost for local development.
913
'http://localhost:3000/';
14+
15+
url = url.trim();
16+
1017
// Make sure to include `https://` when not localhost.
1118
url = url.includes('http') ? url : `https://${url}`;
12-
// Make sure to including trailing `/`.
13-
url = url.charAt(url.length - 1) === '/' ? url : `${url}/`;
19+
20+
// Make sure to include trailing `/`.
21+
url = url.endsWith('/') ? url : `${url}/`;
22+
1423
return url;
1524
};
1625

utils/supabase-admin.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ const upsertProductRecord = async (product: Stripe.Product) => {
2929
console.log(`Product inserted/updated: ${product.id}`);
3030
};
3131

32+
const deleteProductRecord = async (product: Stripe.Product) => {
33+
const { error } = await supabaseAdmin
34+
.from('products')
35+
.delete()
36+
.eq('id', product.id);
37+
if (error) throw error;
38+
console.log(`Product deleted: ${product.id}`);
39+
};
40+
3241
const upsertPriceRecord = async (price: Stripe.Price) => {
3342
const priceData: Price = {
3443
id: price.id,
@@ -49,6 +58,15 @@ const upsertPriceRecord = async (price: Stripe.Price) => {
4958
console.log(`Price inserted/updated: ${price.id}`);
5059
};
5160

61+
const deletePriceRecord = async (price: Stripe.Price) => {
62+
const { error } = await supabaseAdmin
63+
.from('prices')
64+
.delete()
65+
.eq('id', price.id);
66+
if (error) throw error;
67+
console.log(`Price deleted: ${price.id}`);
68+
};
69+
5270
const createOrRetrieveCustomer = async ({
5371
email,
5472
uuid
@@ -179,7 +197,9 @@ const manageSubscriptionStatusChange = async (
179197

180198
export {
181199
upsertProductRecord,
200+
deleteProductRecord,
182201
upsertPriceRecord,
202+
deletePriceRecord,
183203
createOrRetrieveCustomer,
184204
manageSubscriptionStatusChange
185205
};

0 commit comments

Comments
 (0)