🛂 Add new yearly plans and graduated pricing
BREAKING CHANGE: Stripe environment variables have changed. New ones are required. Check out the new Stripe configuration in the docs. Closes #457
This commit is contained in:
@@ -7,6 +7,12 @@ import { workspaceSchema } from '@typebot.io/schemas'
|
||||
import Stripe from 'stripe'
|
||||
import { isDefined } from '@typebot.io/lib'
|
||||
import { z } from 'zod'
|
||||
import {
|
||||
getChatsLimit,
|
||||
getStorageLimit,
|
||||
priceIds,
|
||||
} from '@typebot.io/lib/pricing'
|
||||
import { chatPriceIds, storagePriceIds } from './getSubscription'
|
||||
|
||||
export const updateSubscription = authenticatedProcedure
|
||||
.meta({
|
||||
@@ -25,6 +31,7 @@ export const updateSubscription = authenticatedProcedure
|
||||
additionalChats: z.number(),
|
||||
additionalStorage: z.number(),
|
||||
currency: z.enum(['usd', 'eur']),
|
||||
isYearly: z.boolean(),
|
||||
})
|
||||
)
|
||||
.output(
|
||||
@@ -40,14 +47,11 @@ export const updateSubscription = authenticatedProcedure
|
||||
additionalChats,
|
||||
additionalStorage,
|
||||
currency,
|
||||
isYearly,
|
||||
},
|
||||
ctx: { user },
|
||||
}) => {
|
||||
if (
|
||||
!process.env.STRIPE_SECRET_KEY ||
|
||||
!process.env.STRIPE_ADDITIONAL_CHATS_PRICE_ID ||
|
||||
!process.env.STRIPE_ADDITIONAL_STORAGE_PRICE_ID
|
||||
)
|
||||
if (!process.env.STRIPE_SECRET_KEY)
|
||||
throw new TRPCError({
|
||||
code: 'INTERNAL_SERVER_ERROR',
|
||||
message: 'Stripe environment variables are missing',
|
||||
@@ -70,42 +74,48 @@ export const updateSubscription = authenticatedProcedure
|
||||
customer: workspace.stripeId,
|
||||
})
|
||||
const subscription = data[0] as Stripe.Subscription | undefined
|
||||
const currentStarterPlanItemId = subscription?.items.data.find(
|
||||
(item) => item.price.id === process.env.STRIPE_STARTER_PRICE_ID
|
||||
)?.id
|
||||
const currentProPlanItemId = subscription?.items.data.find(
|
||||
(item) => item.price.id === process.env.STRIPE_PRO_PRICE_ID
|
||||
const currentPlanItemId = subscription?.items.data.find((item) =>
|
||||
[
|
||||
process.env.STRIPE_STARTER_PRODUCT_ID,
|
||||
process.env.STRIPE_PRO_PRODUCT_ID,
|
||||
].includes(item.price.product.toString())
|
||||
)?.id
|
||||
const currentAdditionalChatsItemId = subscription?.items.data.find(
|
||||
(item) => item.price.id === process.env.STRIPE_ADDITIONAL_CHATS_PRICE_ID
|
||||
(item) => chatPriceIds.includes(item.price.id)
|
||||
)?.id
|
||||
const currentAdditionalStorageItemId = subscription?.items.data.find(
|
||||
(item) =>
|
||||
item.price.id === process.env.STRIPE_ADDITIONAL_STORAGE_PRICE_ID
|
||||
(item) => storagePriceIds.includes(item.price.id)
|
||||
)?.id
|
||||
const frequency = isYearly ? 'yearly' : 'monthly'
|
||||
|
||||
const items = [
|
||||
{
|
||||
id: currentStarterPlanItemId ?? currentProPlanItemId,
|
||||
price:
|
||||
plan === Plan.STARTER
|
||||
? process.env.STRIPE_STARTER_PRICE_ID
|
||||
: process.env.STRIPE_PRO_PRICE_ID,
|
||||
id: currentPlanItemId,
|
||||
price: priceIds[plan].base[frequency],
|
||||
quantity: 1,
|
||||
},
|
||||
additionalChats === 0 && !currentAdditionalChatsItemId
|
||||
? undefined
|
||||
: {
|
||||
id: currentAdditionalChatsItemId,
|
||||
price: process.env.STRIPE_ADDITIONAL_CHATS_PRICE_ID,
|
||||
quantity: additionalChats,
|
||||
price: priceIds[plan].chats[frequency],
|
||||
quantity: getChatsLimit({
|
||||
plan,
|
||||
additionalChatsIndex: additionalChats,
|
||||
customChatsLimit: null,
|
||||
}),
|
||||
deleted: subscription ? additionalChats === 0 : undefined,
|
||||
},
|
||||
additionalStorage === 0 && !currentAdditionalStorageItemId
|
||||
? undefined
|
||||
: {
|
||||
id: currentAdditionalStorageItemId,
|
||||
price: process.env.STRIPE_ADDITIONAL_STORAGE_PRICE_ID,
|
||||
quantity: additionalStorage,
|
||||
price: priceIds[plan].storage[frequency],
|
||||
quantity: getStorageLimit({
|
||||
plan,
|
||||
additionalStorageIndex: additionalStorage,
|
||||
customStorageLimit: null,
|
||||
}),
|
||||
deleted: subscription ? additionalStorage === 0 : undefined,
|
||||
},
|
||||
].filter(isDefined)
|
||||
@@ -126,6 +136,9 @@ export const updateSubscription = authenticatedProcedure
|
||||
items,
|
||||
currency,
|
||||
default_payment_method: paymentMethods[0].id,
|
||||
automatic_tax: {
|
||||
enabled: true,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user