diff --git a/server/private/routers/billing/hooks/handleCustomerCreated.ts b/server/private/routers/billing/hooks/handleCustomerCreated.ts index 66ad3a4fa..79dbcea35 100644 --- a/server/private/routers/billing/hooks/handleCustomerCreated.ts +++ b/server/private/routers/billing/hooks/handleCustomerCreated.ts @@ -16,6 +16,7 @@ import { customers, db, subscriptions } from "@server/db"; import { eq } from "drizzle-orm"; import logger from "@server/logger"; import { generateId } from "@server/auth/sessions/app"; +import { handleSubscriptionLifesycle } from "../subscriptionLifecycle"; export async function handleCustomerCreated( customer: Stripe.Customer @@ -62,6 +63,13 @@ export async function handleCustomerCreated( expiresAt: trialExpiresAt, trial: true }); + + // update to the business limits for the trial + await handleSubscriptionLifesycle( + customer.metadata.orgId, + "active", + "tier3" + ); }); logger.info(`Customer with ID ${customer.id} created successfully.`); diff --git a/server/private/routers/billing/subscriptionLifecycle.ts b/server/private/routers/billing/subscriptionLifecycle.ts index 76fb6ec8e..b993a4e1a 100644 --- a/server/private/routers/billing/subscriptionLifecycle.ts +++ b/server/private/routers/billing/subscriptionLifecycle.ts @@ -44,7 +44,7 @@ function getLimitSetForSubscriptionType( export async function handleSubscriptionLifesycle( orgId: string, status: string, - subType: SubscriptionType | null + subType: SubscriptionType | null = null ) { switch (status) { case "active": diff --git a/server/private/routers/org/sendTrialNotification.ts b/server/private/routers/org/sendTrialNotification.ts index c3b7f6518..233010064 100644 --- a/server/private/routers/org/sendTrialNotification.ts +++ b/server/private/routers/org/sendTrialNotification.ts @@ -24,13 +24,18 @@ import { fromError } from "zod-validation-error"; import { sendEmail } from "@server/emails"; import NotifyTrialExpiring from "@server/emails/templates/NotifyTrialExpiring"; import config from "@server/lib/config"; +import { handleSubscriptionLifesycle } from "../billing/subscriptionLifecycle"; const sendTrialNotificationParamsSchema = z.object({ orgId: z.string() }); const sendTrialNotificationBodySchema = z.object({ - notificationType: z.enum(["trial_ending_5d", "trial_ending_24h", "trial_ended"]), + notificationType: z.enum([ + "trial_ending_5d", + "trial_ending_24h", + "trial_ended" + ]), orgName: z.string(), trialEndsAt: z.number(), billingLink: z.string().optional() @@ -69,9 +74,7 @@ async function getOrgAdmins(orgId: string) { ) ); - const byUserId = new Map( - admins.map((a) => [a.userId, a]) - ); + const byUserId = new Map(admins.map((a) => [a.userId, a])); const orgAdmins = Array.from(byUserId.values()).filter( (admin) => admin.email && admin.email.length > 0 ); @@ -108,8 +111,12 @@ export async function sendTrialNotification( } const { orgId } = parsedParams.data; - const { notificationType, orgName, trialEndsAt, billingLink: bodyBillingLink } = - parsedBody.data; + const { + notificationType, + orgName, + trialEndsAt, + billingLink: bodyBillingLink + } = parsedBody.data; // Verify organization exists const org = await db @@ -146,13 +153,17 @@ export async function sendTrialNotification( bodyBillingLink ?? `${config.getRawConfig().app.dashboard_url}/${orgId}/settings/billing`; - const trialEndsAtFormatted = new Date(trialEndsAt * 1000).toLocaleDateString( - "en-US", - { year: "numeric", month: "long", day: "numeric" } - ); + const trialEndsAtFormatted = new Date( + trialEndsAt * 1000 + ).toLocaleDateString("en-US", { + year: "numeric", + month: "long", + day: "numeric" + }); let daysRemaining: number | null; let subject: string; + let resetLimits = false; if (notificationType === "trial_ending_5d") { daysRemaining = 5; @@ -163,6 +174,7 @@ export async function sendTrialNotification( } else { daysRemaining = null; subject = "Your trial has ended"; + resetLimits = true; } let emailsSent = 0; @@ -201,6 +213,14 @@ export async function sendTrialNotification( } } + if (resetLimits) { + // this will only fire if they have not upgraded yet because when upgrading we delete the trial + await handleSubscriptionLifesycle(orgId, "cancled"); + logger.debug( + `Trial ended for org ${orgId}, limits reset to free tier` + ); + } + return response(res, { data: { success: true, @@ -221,4 +241,4 @@ export async function sendTrialNotification( ) ); } -} \ No newline at end of file +}