2
0
Files
bot/ee/packages/billing/api/createCheckoutSession.ts
2024-06-27 12:09:54 +02:00

119 lines
2.6 KiB
TypeScript

import { isAdminWriteWorkspaceForbidden } from '@typebot.io/db-rules/isAdminWriteWorkspaceForbidden'
import { env } from '@typebot.io/env'
import prisma from '@typebot.io/lib/prisma'
import { User } from '@typebot.io/prisma'
import Stripe from 'stripe'
import { createCheckoutSessionUrl } from '../helpers/createCheckoutSessionUrl'
import { TRPCError } from '@trpc/server'
type Props = {
workspaceId: string
user: Pick<User, 'email' | 'id'>
returnUrl: string
email: string
company: string
plan: 'STARTER' | 'PRO'
currency: 'usd' | 'eur'
vat?: {
type: string
value: string
}
}
export const createCheckoutSession = async ({
workspaceId,
user,
returnUrl,
email,
company,
plan,
currency,
vat,
}: Props) => {
if (!env.STRIPE_SECRET_KEY)
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
message: 'Stripe environment variables are missing',
})
const workspace = await prisma.workspace.findFirst({
where: {
id: workspaceId,
},
select: {
stripeId: true,
members: {
select: {
userId: true,
role: true,
},
},
},
})
if (!workspace || isAdminWriteWorkspaceForbidden(workspace, user))
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Workspace not found',
})
if (workspace.stripeId)
throw new TRPCError({
code: 'BAD_REQUEST',
message: 'Customer already exists, use updateSubscription endpoint.',
})
const stripe = new Stripe(env.STRIPE_SECRET_KEY, {
apiVersion: '2022-11-15',
})
await prisma.user.updateMany({
where: {
id: user.id,
},
data: {
company,
},
})
const existingCustomer = await stripe.customers.list({
email,
})
if (existingCustomer && email !== existingCustomer.data[0].email)
throw new TRPCError({
code: 'BAD_REQUEST',
message: 'Make sure to log in with the same email as the one provided',
})
const customerData = {
email,
name: company,
metadata: { workspaceId },
tax_id_data: vat
? [vat as Stripe.CustomerCreateParams.TaxIdDatum]
: undefined,
}
const customer =
existingCustomer.data.length > 0
? await stripe.customers.update(existingCustomer.data[0].id, customerData)
: await stripe.customers.create(customerData)
const checkoutUrl = await createCheckoutSessionUrl(stripe)({
customerId: customer.id,
userId: user.id,
workspaceId,
currency,
plan,
returnUrl,
})
if (!checkoutUrl)
throw new TRPCError({
code: 'INTERNAL_SERVER_ERROR',
message: 'Stripe checkout session creation failed',
})
return {
checkoutUrl,
}
}