From 191aeb0214e66ad56f36525f3136ad30caa09f7b Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Tue, 13 Feb 2024 10:23:13 +0100 Subject: [PATCH] :bug: (billing) Fix webhook calls when workspace was deleted --- .../auth/components/OnboardingPage.tsx | 2 +- .../features/workspace/api/deleteWorkspace.ts | 19 ++++++++++++++++++- apps/builder/src/pages/api/stripe/webhook.ts | 11 +++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/apps/builder/src/features/auth/components/OnboardingPage.tsx b/apps/builder/src/features/auth/components/OnboardingPage.tsx index 203ad2289..be63e38da 100644 --- a/apps/builder/src/features/auth/components/OnboardingPage.tsx +++ b/apps/builder/src/features/auth/components/OnboardingPage.tsx @@ -77,7 +77,7 @@ export const OnboardingPage = () => { if (isOtherCategory) setOnboardingReplies((prev) => ({ ...prev, - categories: prev.onboardingCategories + onboardingCategories: prev.onboardingCategories ? [...prev.onboardingCategories, answer.message] : [answer.message], })) diff --git a/apps/builder/src/features/workspace/api/deleteWorkspace.ts b/apps/builder/src/features/workspace/api/deleteWorkspace.ts index 1b1f9bf75..7c8d993ec 100644 --- a/apps/builder/src/features/workspace/api/deleteWorkspace.ts +++ b/apps/builder/src/features/workspace/api/deleteWorkspace.ts @@ -3,6 +3,9 @@ import { authenticatedProcedure } from '@/helpers/server/trpc' import { z } from 'zod' import { isAdminWriteWorkspaceForbidden } from '../helpers/isAdminWriteWorkspaceForbidden' import { TRPCError } from '@trpc/server' +import { isNotEmpty } from '@typebot.io/lib/utils' +import Stripe from 'stripe' +import { env } from '@typebot.io/env' export const deleteWorkspace = authenticatedProcedure .meta({ @@ -38,9 +41,23 @@ export const deleteWorkspace = authenticatedProcedure throw new TRPCError({ code: 'NOT_FOUND', message: 'No workspaces found' }) await prisma.workspace.deleteMany({ - where: { members: { some: { userId: user.id } }, id: workspaceId }, + where: { id: workspaceId }, }) + if (isNotEmpty(workspace.stripeId) && env.STRIPE_SECRET_KEY) { + const stripe = new Stripe(env.STRIPE_SECRET_KEY, { + apiVersion: '2022-11-15', + }) + + const subscriptions = await stripe.subscriptions.list({ + customer: workspace.stripeId, + }) + + for (const subscription of subscriptions.data) { + await stripe.subscriptions.cancel(subscription.id) + } + } + return { message: 'Workspace deleted', } diff --git a/apps/builder/src/pages/api/stripe/webhook.ts b/apps/builder/src/pages/api/stripe/webhook.ts index 0796772e6..dd0ee237a 100644 --- a/apps/builder/src/pages/api/stripe/webhook.ts +++ b/apps/builder/src/pages/api/stripe/webhook.ts @@ -234,6 +234,17 @@ const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => { outstandingInvoices.data.filter( (invoice) => invoice.amount_due > prices['PRO'] * 100 ) + + const workspaceExist = + (await prisma.workspace.count({ + where: { + stripeId: subscription.customer as string, + }, + })) > 0 + + if (!workspaceExist) + return res.send({ message: 'Workspace not found, skipping...' }) + const workspace = await prisma.workspace.update({ where: { stripeId: subscription.customer as string,