✨ Add usage-based new pricing plans
This commit is contained in:
committed by
Baptiste Arnaud
parent
6a1eaea700
commit
898367a33b
@@ -1,28 +0,0 @@
|
||||
import { createTransport } from 'nodemailer'
|
||||
import { env } from 'utils'
|
||||
|
||||
export const sendEmailNotification = ({
|
||||
to,
|
||||
subject,
|
||||
content,
|
||||
}: {
|
||||
to: string
|
||||
subject: string
|
||||
content: string
|
||||
}) => {
|
||||
const transporter = createTransport({
|
||||
host: process.env.SMTP_HOST,
|
||||
port: Number(process.env.SMTP_PORT),
|
||||
auth: {
|
||||
user: process.env.SMTP_USERNAME,
|
||||
pass: process.env.SMTP_PASSWORD,
|
||||
},
|
||||
})
|
||||
|
||||
return transporter.sendMail({
|
||||
from: env('SMTP_FROM'),
|
||||
to,
|
||||
subject,
|
||||
html: content,
|
||||
})
|
||||
}
|
||||
@@ -2,12 +2,11 @@ import { setUser } from '@sentry/nextjs'
|
||||
import { User } from 'db'
|
||||
import { NextApiRequest } from 'next'
|
||||
import { getSession } from 'next-auth/react'
|
||||
import { env } from 'utils'
|
||||
|
||||
const mockedUser: User = {
|
||||
id: 'proUser',
|
||||
name: 'Pro user',
|
||||
email: 'pro-user@email.com',
|
||||
export const mockedUser: User = {
|
||||
id: 'userId',
|
||||
name: 'John Doe',
|
||||
email: 'user@email.com',
|
||||
company: null,
|
||||
createdAt: new Date(),
|
||||
emailVerified: null,
|
||||
@@ -22,7 +21,6 @@ export const getAuthenticatedUser = async (
|
||||
req: NextApiRequest
|
||||
): Promise<User | undefined> => {
|
||||
const session = await getSession({ req })
|
||||
if (env('E2E_TEST') === 'true' && !session?.user) return mockedUser
|
||||
if (!session?.user || !('id' in session.user)) return
|
||||
const user = session.user as User
|
||||
setUser({ id: user.id, email: user.email ?? undefined })
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
import { Plan, User } from 'db'
|
||||
import { loadStripe } from '@stripe/stripe-js/pure'
|
||||
import { env, isDefined, isEmpty, sendRequest } from 'utils'
|
||||
|
||||
type Props = {
|
||||
user: User
|
||||
customerId?: string
|
||||
currency: 'usd' | 'eur'
|
||||
plan: 'pro' | 'team'
|
||||
workspaceId: string
|
||||
}
|
||||
|
||||
export const pay = async ({
|
||||
customerId,
|
||||
...props
|
||||
}: Props): Promise<{ newPlan: Plan } | undefined | void> =>
|
||||
isDefined(customerId)
|
||||
? updatePlan({ ...props, customerId })
|
||||
: redirectToCheckout(props)
|
||||
|
||||
const updatePlan = async ({
|
||||
customerId,
|
||||
plan,
|
||||
workspaceId,
|
||||
currency,
|
||||
}: Omit<Props, 'user'>): Promise<{ newPlan: Plan } | undefined> => {
|
||||
const { data, error } = await sendRequest<{ message: string }>({
|
||||
method: 'POST',
|
||||
url: '/api/stripe/update-subscription',
|
||||
body: { workspaceId, plan, customerId, currency },
|
||||
})
|
||||
if (error || !data) return
|
||||
return { newPlan: plan === 'team' ? Plan.TEAM : Plan.PRO }
|
||||
}
|
||||
|
||||
const redirectToCheckout = async ({
|
||||
user,
|
||||
currency,
|
||||
plan,
|
||||
workspaceId,
|
||||
}: Omit<Props, 'customerId'>) => {
|
||||
if (isEmpty(env('STRIPE_PUBLIC_KEY')))
|
||||
throw new Error('NEXT_PUBLIC_STRIPE_PUBLIC_KEY is missing in env')
|
||||
const { data, error } = await sendRequest<{ sessionId: string }>({
|
||||
method: 'POST',
|
||||
url: '/api/stripe/checkout',
|
||||
body: {
|
||||
email: user.email,
|
||||
currency,
|
||||
plan,
|
||||
workspaceId,
|
||||
href: location.origin + location.pathname,
|
||||
},
|
||||
})
|
||||
if (error || !data) return
|
||||
const stripe = await loadStripe(env('STRIPE_PUBLIC_KEY') as string)
|
||||
await stripe?.redirectToCheckout({
|
||||
sessionId: data?.sessionId,
|
||||
})
|
||||
}
|
||||
@@ -119,3 +119,6 @@ export const timeSince = (date: string) => {
|
||||
|
||||
export const isCloudProdInstance = () =>
|
||||
typeof window !== 'undefined' && window.location.hostname === 'app.typebot.io'
|
||||
|
||||
export const numberWithCommas = (x: number) =>
|
||||
x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
||||
|
||||
@@ -19,7 +19,19 @@ export const useWorkspaces = ({ userId }: { userId?: string }) => {
|
||||
}
|
||||
|
||||
export const createNewWorkspace = async (
|
||||
body: Omit<Workspace, 'id' | 'icon' | 'createdAt' | 'stripeId'>
|
||||
body: Omit<
|
||||
Workspace,
|
||||
| 'id'
|
||||
| 'icon'
|
||||
| 'createdAt'
|
||||
| 'stripeId'
|
||||
| 'additionalChatsIndex'
|
||||
| 'additionalStorageIndex'
|
||||
| 'chatsLimitFirstEmailSentAt'
|
||||
| 'chatsLimitSecondEmailSentAt'
|
||||
| 'storageLimitFirstEmailSentAt'
|
||||
| 'storageLimitSecondEmailSentAt'
|
||||
>
|
||||
) =>
|
||||
sendRequest<{
|
||||
workspace: Workspace
|
||||
@@ -57,8 +69,6 @@ export const planToReadable = (plan?: Plan) => {
|
||||
return 'Offered'
|
||||
case Plan.PRO:
|
||||
return 'Pro'
|
||||
case Plan.TEAM:
|
||||
return 'Team'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user