Skip to content

Commit f11c4dd

Browse files
authored
fix: platform billing portal (calcom#23975)
* fix: check if team is platform or not when sending billingPortalUrl * update team repository * fix: pass teamId explicitely for platform team * fix: coderabbit feedback * fix: merge conflicts * fix: merge conflicts * fix: make sure we pass in the correct subsciption id * fix: implement PR feedback
1 parent 386f60c commit f11c4dd

3 files changed

Lines changed: 53 additions & 9 deletions

File tree

apps/web/modules/settings/platform/billing/billing-view.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,18 @@ declare global {
3030
export default function PlatformBillingUpgrade() {
3131
const pathname = usePathname();
3232
const { t } = useLocale();
33+
const { isUserLoading, isUserBillingDataLoading, isPlatformUser, userBillingData, isPaidUser, userOrgId } =
34+
useGetUserAttributes();
35+
3336
const returnTo = pathname;
34-
const billingHref = `/api/integrations/stripepayment/portal?returnTo=${WEBAPP_URL}${returnTo}`;
37+
const teamId = `teamId=${userOrgId}`;
38+
const billingHref = `/api/integrations/stripepayment/portal?returnTo=${WEBAPP_URL}${returnTo}&${teamId}`;
3539

3640
const onContactSupportClick = async () => {
3741
if (window.Support) {
3842
window.Support.open();
3943
}
4044
};
41-
const { isUserLoading, isUserBillingDataLoading, isPlatformUser, userBillingData, isPaidUser, userOrgId } =
42-
useGetUserAttributes();
4345

4446
const { mutateAsync: removeTeamSubscription, isPending: isRemoveTeamSubscriptionLoading } =
4547
useUnsubscribeTeamToStripe({

packages/app-store/stripepayment/lib/services/team/TeamBillingPortalService.ts

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import logger from "@calcom/lib/logger";
2+
import type { Prisma } from "@calcom/prisma/client";
23
import { MembershipRole } from "@calcom/prisma/enums";
34
import { teamMetadataSchema } from "@calcom/prisma/zod-utils";
45

@@ -18,25 +19,53 @@ export class TeamBillingPortalService extends BillingPortalService {
1819
});
1920
}
2021

22+
async getValidatedTeamSubscriptionId(metadata: Prisma.JsonValue) {
23+
const teamMetadataParsed = teamMetadataSchema.safeParse(metadata);
24+
25+
if (!teamMetadataParsed.success || !teamMetadataParsed.data?.subscriptionId) {
26+
return null;
27+
}
28+
29+
return teamMetadataParsed.data.subscriptionId;
30+
}
31+
32+
async getValidatedTeamSubscriptionIdForPlatform(subscriptionId?: string | null) {
33+
if (!subscriptionId) {
34+
return null;
35+
}
36+
37+
return subscriptionId;
38+
}
39+
2140
async getCustomerId(teamId: number): Promise<string | null> {
2241
const log = logger.getSubLogger({ prefix: ["TeamBillingPortalService", "getCustomerId"] });
2342

24-
const team = await this.teamRepository.findById({ id: teamId });
43+
const team = await this.teamRepository.findByIdIncludePlatformBilling({ id: teamId });
2544
if (!team) return null;
2645

27-
const teamMetadataParsed = teamMetadataSchema.safeParse(team.metadata);
46+
let teamSubscriptionId = "";
2847

29-
if (!teamMetadataParsed.success || !teamMetadataParsed.data?.subscriptionId) {
30-
return null;
48+
if (team.isPlatform) {
49+
const subscriptionId = await this.getValidatedTeamSubscriptionIdForPlatform(
50+
team.platformBilling?.subscriptionId
51+
);
52+
53+
if (!subscriptionId) return null;
54+
teamSubscriptionId = subscriptionId;
55+
} else {
56+
const subscriptionId = await this.getValidatedTeamSubscriptionId(team.metadata);
57+
58+
if (!subscriptionId) return null;
59+
teamSubscriptionId = subscriptionId;
3160
}
3261

3362
try {
34-
const subscription = await getSubscriptionFromId(teamMetadataParsed.data.subscriptionId);
63+
const subscription = await getSubscriptionFromId(teamSubscriptionId);
3564

3665
if (!subscription?.customer) {
3766
log.warn("Subscription found but no customer ID", {
3867
teamId,
39-
subscriptionId: teamMetadataParsed.data.subscriptionId,
68+
teamSubscriptionId,
4069
});
4170
return null;
4271
}

packages/lib/server/repository/team.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,19 @@ export class TeamRepository {
183183
return getParsedTeam(team);
184184
}
185185

186+
async findByIdIncludePlatformBilling({ id }: { id: number }) {
187+
const team = await this.prismaClient.team.findUnique({
188+
where: {
189+
id,
190+
},
191+
select: { ...teamSelect, platformBilling: true },
192+
});
193+
if (!team) {
194+
return null;
195+
}
196+
return getParsedTeam(team);
197+
}
198+
186199
async findAllByParentId({
187200
parentId,
188201
select = teamSelect,

0 commit comments

Comments
 (0)