From c2e1c289eb839e5d26b3908bcecd40deaca533f9 Mon Sep 17 00:00:00 2001 From: Luke Vella Date: Sat, 23 Nov 2024 14:18:39 +0000 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Handle=20failed=20payments?= =?UTF-8?q?=20in=20webhook=20(#1443)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web/src/app/api/stripe/webhook/route.ts | 51 +++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/apps/web/src/app/api/stripe/webhook/route.ts b/apps/web/src/app/api/stripe/webhook/route.ts index 3cb48dd24..f141e892b 100644 --- a/apps/web/src/app/api/stripe/webhook/route.ts +++ b/apps/web/src/app/api/stripe/webhook/route.ts @@ -91,7 +91,56 @@ export async function POST(request: NextRequest) { break; } - case "customer.subscription.deleted": + case "customer.subscription.deleted": { + const { id } = event.data.object as Stripe.Subscription; + const subscription = await stripe.subscriptions.retrieve(id); + + // void any unpaid invoices + const invoices = await stripe.invoices.list({ + subscription: subscription.id, + status: "open", + }); + + for (const invoice of invoices.data) { + await stripe.invoices.voidInvoice(invoice.id); + } + + // remove the subscription from the user + await prisma.user.update({ + where: { + subscriptionId: subscription.id, + }, + data: { + subscriptionId: null, + }, + }); + // delete the subscription from the database + await prisma.subscription.delete({ + where: { + id: subscription.id, + }, + }); + + try { + const { userId } = subscriptionMetadataSchema.parse( + subscription.metadata, + ); + + posthog?.capture({ + distinctId: userId, + event: "subscription cancel", + properties: { + $set: { + tier: "hobby", + }, + }, + }); + } catch (e) { + Sentry.captureException(e); + } + + break; + } case "customer.subscription.updated": case "customer.subscription.created": { const { id } = event.data.object as Stripe.Subscription;