From dcef99bf4989b238c7c9a509e2f9c0543d8cdac4 Mon Sep 17 00:00:00 2001 From: Rajiv Sahal Date: Fri, 26 Sep 2025 11:26:25 +0530 Subject: [PATCH] fix: update org billing portal service to handle platform orgs (#24088) --- .../OrganizationBillingPortalService.ts | 47 +++++++++++++++---- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/packages/app-store/stripepayment/lib/services/organization/OrganizationBillingPortalService.ts b/packages/app-store/stripepayment/lib/services/organization/OrganizationBillingPortalService.ts index d58c0eae58..844a74683c 100644 --- a/packages/app-store/stripepayment/lib/services/organization/OrganizationBillingPortalService.ts +++ b/packages/app-store/stripepayment/lib/services/organization/OrganizationBillingPortalService.ts @@ -1,4 +1,5 @@ import logger from "@calcom/lib/logger"; +import type { Prisma } from "@calcom/prisma/client"; import { MembershipRole } from "@calcom/prisma/enums"; import { teamMetadataSchema } from "@calcom/prisma/zod-utils"; @@ -23,25 +24,53 @@ export class OrganizationBillingPortalService extends BillingPortalService { }); } - async getCustomerId(teamId: number): Promise { - const log = logger.getSubLogger({ prefix: ["OrganizationBillingPortalService", "getCustomerId"] }); - - const team = await this.teamRepository.findById({ id: teamId }); - if (!team) return null; - - const teamMetadataParsed = teamMetadataSchema.safeParse(team.metadata); + async getValidatedTeamSubscriptionId(metadata: Prisma.JsonValue) { + const teamMetadataParsed = teamMetadataSchema.safeParse(metadata); if (!teamMetadataParsed.success || !teamMetadataParsed.data?.subscriptionId) { return null; } + return teamMetadataParsed.data.subscriptionId; + } + + async getValidatedTeamSubscriptionIdForPlatform(subscriptionId?: string | null) { + if (!subscriptionId) { + return null; + } + + return subscriptionId; + } + + async getCustomerId(teamId: number): Promise { + const log = logger.getSubLogger({ prefix: ["OrganizationBillingPortalService", "getCustomerId"] }); + + const team = await this.teamRepository.findByIdIncludePlatformBilling({ id: teamId }); + if (!team) return null; + + let teamSubscriptionId = ""; + + if (team.isPlatform) { + const subscriptionId = await this.getValidatedTeamSubscriptionIdForPlatform( + team.platformBilling?.subscriptionId + ); + + if (!subscriptionId) return null; + teamSubscriptionId = subscriptionId; + } else { + const subscriptionId = await this.getValidatedTeamSubscriptionId(team.metadata); + + if (!subscriptionId) return null; + teamSubscriptionId = subscriptionId; + } + try { - const subscription = await getSubscriptionFromId(teamMetadataParsed.data.subscriptionId); + const subscription = await getSubscriptionFromId(teamSubscriptionId); if (!subscription?.customer) { log.warn("Subscription found but no customer ID", { teamId, - subscriptionId: teamMetadataParsed.data.subscriptionId, + subscriptionId: teamSubscriptionId, }); return null; }