📈 (billing) Track when workspace subscription is cancelled
This commit is contained in:
@@ -134,7 +134,6 @@ export const createCheckoutSessionUrl =
|
|||||||
(stripe: Stripe) =>
|
(stripe: Stripe) =>
|
||||||
async ({
|
async ({
|
||||||
customerId,
|
customerId,
|
||||||
userId,
|
|
||||||
workspaceId,
|
workspaceId,
|
||||||
currency,
|
currency,
|
||||||
plan,
|
plan,
|
||||||
@@ -158,7 +157,6 @@ export const createCheckoutSessionUrl =
|
|||||||
plan,
|
plan,
|
||||||
additionalChats,
|
additionalChats,
|
||||||
additionalStorage,
|
additionalStorage,
|
||||||
userId,
|
|
||||||
},
|
},
|
||||||
currency,
|
currency,
|
||||||
billing_address_collection: 'required',
|
billing_address_collection: 'required',
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ export const createCustomCheckoutSession = authenticatedProcedure
|
|||||||
mode: 'subscription',
|
mode: 'subscription',
|
||||||
metadata: {
|
metadata: {
|
||||||
claimableCustomPlanId: workspace.claimableCustomPlan.id,
|
claimableCustomPlanId: workspace.claimableCustomPlan.id,
|
||||||
userId: user.id,
|
|
||||||
},
|
},
|
||||||
currency: workspace.claimableCustomPlan.currency,
|
currency: workspace.claimableCustomPlan.currency,
|
||||||
billing_address_collection: 'required',
|
billing_address_collection: 'required',
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import Stripe from 'stripe'
|
|||||||
import Cors from 'micro-cors'
|
import Cors from 'micro-cors'
|
||||||
import { buffer } from 'micro'
|
import { buffer } from 'micro'
|
||||||
import prisma from '@/lib/prisma'
|
import prisma from '@/lib/prisma'
|
||||||
import { Plan } from '@typebot.io/prisma'
|
import { Plan, WorkspaceRole } from '@typebot.io/prisma'
|
||||||
import { RequestHandler } from 'next/dist/server/next'
|
import { RequestHandler } from 'next/dist/server/next'
|
||||||
import { sendTelemetryEvents } from '@typebot.io/lib/telemetry/sendTelemetryEvent'
|
import { sendTelemetryEvents } from '@typebot.io/lib/telemetry/sendTelemetryEvent'
|
||||||
import { PublicTypebot, Typebot } from '@typebot.io/schemas'
|
import { PublicTypebot, Typebot } from '@typebot.io/schemas'
|
||||||
@@ -52,18 +52,13 @@ const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||||||
}
|
}
|
||||||
| { claimableCustomPlanId: string; userId: string }
|
| { claimableCustomPlanId: string; userId: string }
|
||||||
if ('plan' in metadata) {
|
if ('plan' in metadata) {
|
||||||
const {
|
const { workspaceId, plan, additionalChats, additionalStorage } =
|
||||||
workspaceId,
|
metadata
|
||||||
plan,
|
|
||||||
additionalChats,
|
|
||||||
additionalStorage,
|
|
||||||
userId,
|
|
||||||
} = metadata
|
|
||||||
if (!workspaceId || !plan || !additionalChats || !additionalStorage)
|
if (!workspaceId || !plan || !additionalChats || !additionalStorage)
|
||||||
return res
|
return res
|
||||||
.status(500)
|
.status(500)
|
||||||
.send({ message: `Couldn't retrieve valid metadata` })
|
.send({ message: `Couldn't retrieve valid metadata` })
|
||||||
await prisma.workspace.update({
|
const workspace = await prisma.workspace.update({
|
||||||
where: { id: workspaceId },
|
where: { id: workspaceId },
|
||||||
data: {
|
data: {
|
||||||
plan,
|
plan,
|
||||||
@@ -72,20 +67,31 @@ const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||||||
additionalStorageIndex: parseInt(additionalStorage),
|
additionalStorageIndex: parseInt(additionalStorage),
|
||||||
isQuarantined: false,
|
isQuarantined: false,
|
||||||
},
|
},
|
||||||
})
|
include: {
|
||||||
|
members: {
|
||||||
await sendTelemetryEvents([
|
select: { user: { select: { id: true } } },
|
||||||
{
|
where: {
|
||||||
name: 'Subscription updated',
|
role: WorkspaceRole.ADMIN,
|
||||||
workspaceId,
|
},
|
||||||
userId,
|
|
||||||
data: {
|
|
||||||
plan,
|
|
||||||
additionalChatsIndex: parseInt(additionalChats),
|
|
||||||
additionalStorageIndex: parseInt(additionalStorage),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
])
|
})
|
||||||
|
|
||||||
|
for (const user of workspace.members.map((member) => member.user)) {
|
||||||
|
if (!user?.id) continue
|
||||||
|
await sendTelemetryEvents([
|
||||||
|
{
|
||||||
|
name: 'Subscription updated',
|
||||||
|
workspaceId,
|
||||||
|
userId: user.id,
|
||||||
|
data: {
|
||||||
|
plan,
|
||||||
|
additionalChatsIndex: parseInt(additionalChats),
|
||||||
|
additionalStorageIndex: parseInt(additionalStorage),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const { claimableCustomPlanId, userId } = metadata
|
const { claimableCustomPlanId, userId } = metadata
|
||||||
if (!claimableCustomPlanId)
|
if (!claimableCustomPlanId)
|
||||||
@@ -139,7 +145,32 @@ const webhookHandler = async (req: NextApiRequest, res: NextApiResponse) => {
|
|||||||
customStorageLimit: null,
|
customStorageLimit: null,
|
||||||
customSeatsLimit: null,
|
customSeatsLimit: null,
|
||||||
},
|
},
|
||||||
|
include: {
|
||||||
|
members: {
|
||||||
|
select: { user: { select: { id: true } } },
|
||||||
|
where: {
|
||||||
|
role: WorkspaceRole.ADMIN,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
for (const user of workspace.members.map((member) => member.user)) {
|
||||||
|
if (!user?.id) continue
|
||||||
|
await sendTelemetryEvents([
|
||||||
|
{
|
||||||
|
name: 'Subscription updated',
|
||||||
|
workspaceId: workspace.id,
|
||||||
|
userId: user.id,
|
||||||
|
data: {
|
||||||
|
plan: Plan.FREE,
|
||||||
|
additionalChatsIndex: 0,
|
||||||
|
additionalStorageIndex: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
const typebots = (await prisma.typebot.findMany({
|
const typebots = (await prisma.typebot.findMany({
|
||||||
where: {
|
where: {
|
||||||
workspaceId: workspace.id,
|
workspaceId: workspace.id,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ const checkSubscriptionsStatus = async () => {
|
|||||||
apiVersion: '2022-11-15',
|
apiVersion: '2022-11-15',
|
||||||
})
|
})
|
||||||
|
|
||||||
let activeSubscriptions = 0
|
let totalActiveSubscriptions = 0
|
||||||
for (const workspace of workspacesWithPaidPlan) {
|
for (const workspace of workspacesWithPaidPlan) {
|
||||||
if (!workspace.stripeId) {
|
if (!workspace.stripeId) {
|
||||||
console.log('No stripe ID', workspace.id)
|
console.log('No stripe ID', workspace.id)
|
||||||
@@ -35,12 +35,12 @@ const checkSubscriptionsStatus = async () => {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (subscription.status === 'active') {
|
if (subscription.status === 'active') {
|
||||||
activeSubscriptions++
|
totalActiveSubscriptions++
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
console.log(`${workspace.id} - ${workspace.name} - ${subscription.status}`)
|
console.log(`${workspace.id} - ${workspace.name} - ${subscription.status}`)
|
||||||
}
|
}
|
||||||
console.log('Active subscriptions', activeSubscriptions)
|
console.log('Active subscriptions', totalActiveSubscriptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkSubscriptionsStatus()
|
checkSubscriptionsStatus()
|
||||||
|
|||||||
Reference in New Issue
Block a user