diff --git a/.env.example b/.env.example index d609d8d670..ceacae501a 100644 --- a/.env.example +++ b/.env.example @@ -259,6 +259,8 @@ NEXT_PUBLIC_AVAILABILITY_SCHEDULE_INTERVAL= # This variable should only be set to 1 or true if you are in a non-prod environment and you want to # use organizations ORGANIZATIONS_ENABLED= +NEXT_PUBLIC_ORGANIZATIONS_MIN_SELF_SERVE_SEATS=30 +NEXT_PUBLIC_ORGANIZATIONS_SELF_SERVE_PRICE=3700 # $37.00 per seat # This variable should only be set to 1 or true if you want to autolink external provider sing-ups with # existing organizations based on email domain address diff --git a/packages/features/ee/teams/lib/payments.ts b/packages/features/ee/teams/lib/payments.ts index 3b02233860..487f4de388 100644 --- a/packages/features/ee/teams/lib/payments.ts +++ b/packages/features/ee/teams/lib/payments.ts @@ -3,7 +3,13 @@ import { z } from "zod"; import { getStripeCustomerIdFromUserId } from "@calcom/app-store/stripepayment/lib/customer"; import stripe from "@calcom/app-store/stripepayment/lib/server"; -import { IS_PRODUCTION, MINIMUM_NUMBER_OF_ORG_SEATS, WEBAPP_URL } from "@calcom/lib/constants"; +import { + IS_PRODUCTION, + MINIMUM_NUMBER_OF_ORG_SEATS, + ORGANIZATION_SELF_SERVE_MIN_SEATS, + ORGANIZATION_SELF_SERVE_PRICE, + WEBAPP_URL, +} from "@calcom/lib/constants"; import logger from "@calcom/lib/logger"; import { safeStringify } from "@calcom/lib/safeStringify"; import prisma from "@calcom/prisma"; @@ -121,15 +127,23 @@ export const purchaseTeamOrOrgSubscription = async (input: { let priceId: string | undefined; if (pricePerSeat) { - const customPriceObj = await getPriceObject(fixedPrice); - priceId = await createPrice({ - isOrg: !!isOrg, - teamId, - pricePerSeat, - billingPeriod, - product: customPriceObj.product as string, // We don't expand the object from stripe so just use the product as ID - currency: customPriceObj.currency, - }); + if ( + isOrg && + pricePerSeat === ORGANIZATION_SELF_SERVE_PRICE && + seats === ORGANIZATION_SELF_SERVE_MIN_SEATS + ) { + priceId = fixedPrice as string; + } else { + const customPriceObj = await getPriceObject(fixedPrice); + priceId = await createPrice({ + isOrg: !!isOrg, + teamId, + pricePerSeat, + billingPeriod, + product: customPriceObj.product as string, // We don't expand the object from stripe so just use the product as ID + currency: customPriceObj.currency, + }); + } } else { priceId = fixedPrice as string; } diff --git a/packages/lib/constants.ts b/packages/lib/constants.ts index 8e72f3cca5..89f8d1a3ca 100644 --- a/packages/lib/constants.ts +++ b/packages/lib/constants.ts @@ -104,12 +104,16 @@ export const ENABLE_PROFILE_SWITCHER = process.env.NEXT_PUBLIC_ENABLE_PROFILE_SW export const ALLOWED_HOSTNAMES = JSON.parse(`[${process.env.ALLOWED_HOSTNAMES || ""}]`) as string[]; export const RESERVED_SUBDOMAINS = JSON.parse(`[${process.env.RESERVED_SUBDOMAINS || ""}]`) as string[]; +export const ORGANIZATION_SELF_SERVE_MIN_SEATS = + process.env.NEXT_PUBLIC_ORGANIZATIONS_MIN_SELF_SERVE_SEATS || 30; +export const ORGANIZATION_SELF_SERVE_PRICE = process.env.NEXT_PUBLIC_ORGANIZATIONS_SELF_SERVE_PRICE || 3700; + +export const ORGANIZATION_MIN_SEATS = 30; + export const ENABLE_INFINITE_EVENT_TYPES_FOR_ORG = JSON.parse( `[${process.env.ENABLE_INFINITE_EVENT_TYPES_FOR_ORG || ""}]` ) as string[]; -export const ORGANIZATION_MIN_SEATS = 30; - // Needed for emails in E2E export const IS_MAILHOG_ENABLED = process.env.E2E_TEST_MAILHOG_ENABLED === "1"; export const CALCOM_VERSION = process.env.NEXT_PUBLIC_CALCOM_VERSION as string; diff --git a/turbo.json b/turbo.json index 1c7fe30de1..4275e3fc89 100644 --- a/turbo.json +++ b/turbo.json @@ -338,6 +338,8 @@ "NEXT_PUBLIC_VERCEL_ENV", "NEXT_PUBLIC_VERCEL_BRANCH_URL", "NEXT_PUBLIC_GTM_ID", + "NEXT_PUBLIC_ORGANIZATIONS_MIN_SELF_SERVE_SEATS", + "NEXT_PUBLIC_ORGANIZATIONS_SELF_SERVE_PRICE", "NEXT_RUNTIME", "NEXTAUTH_COOKIE_DOMAIN", "NEXTAUTH_SECRET",