@@ -2,6 +2,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
22
33import { WEBAPP_URL } from "@calcom/lib/constants" ;
44import { getSafeRedirectUrl } from "@calcom/lib/getSafeRedirectUrl" ;
5+ import logger from "@calcom/lib/logger" ;
56import { TeamRepository } from "@calcom/lib/server/repository/team" ;
67import prisma from "@calcom/prisma" ;
78import { teamMetadataSchema } from "@calcom/prisma/zod-utils" ;
@@ -10,6 +11,21 @@ import { getStripeCustomerIdFromUserId } from "../lib/customer";
1011import stripe from "../lib/server" ;
1112import { getSubscriptionFromId } from "../lib/subscriptions" ;
1213
14+ const getBillingPortalUrl = async ( customerId : string , return_url : string ) => {
15+ const log = logger . getSubLogger ( { prefix : [ "getBillingPortalUrl" ] } ) ;
16+ try {
17+ const portalSession = await stripe . billingPortal . sessions . create ( {
18+ customer : customerId ,
19+ return_url,
20+ } ) ;
21+
22+ return portalSession . url ;
23+ } catch ( e ) {
24+ log . error ( `Failed to create billing portal session for ${ customerId } : ${ e } ` ) ;
25+ throw new Error ( "Failed to create billing portal session" ) ;
26+ }
27+ } ;
28+
1329export default async function handler ( req : NextApiRequest , res : NextApiResponse ) {
1430 if ( req . method !== "POST" && req . method !== "GET" )
1531 return res . status ( 405 ) . json ( { message : "Method not allowed" } ) ;
@@ -18,35 +34,29 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
1834
1935 const userId = req . session . user . id ;
2036 const teamId = req . query . teamId ? parseInt ( req . query . teamId as string ) : null ;
21-
37+ let return_url = ` ${ WEBAPP_URL } /settings/billing` ;
2238 if ( ! teamId ) {
23- return res . status ( 400 ) . json ( { message : "Team ID is required" } ) ;
39+ const customerId = await getStripeCustomerIdFromUserId ( userId ) ;
40+ if ( ! customerId ) return res . status ( 404 ) . json ( { message : "CustomerId not found" } ) ;
41+
42+ const billingPortalUrl = await getBillingPortalUrl ( customerId , return_url ) ;
43+
44+ return res . redirect ( 302 , billingPortalUrl ) ;
2445 }
2546
2647 const teamRepository = new TeamRepository ( prisma ) ;
2748 const team = await teamRepository . getTeamByIdIfUserIsAdmin ( {
2849 teamId,
2950 userId,
3051 } ) ;
31- let return_url = `${ WEBAPP_URL } /settings/billing` ;
52+
53+ if ( ! team ) return res . status ( 404 ) . json ( { message : "Team not found" } ) ;
3254
3355 if ( typeof req . query . returnTo === "string" ) {
3456 const safeRedirectUrl = getSafeRedirectUrl ( req . query . returnTo ) ;
3557 if ( safeRedirectUrl ) return_url = safeRedirectUrl ;
3658 }
3759
38- if ( ! team ) {
39- const customerId = await getStripeCustomerIdFromUserId ( userId ) ;
40- if ( ! customerId ) return res . status ( 404 ) . json ( { message : "CustomerId not found" } ) ;
41-
42- const portalSession = await stripe . billingPortal . sessions . create ( {
43- customer : customerId ,
44- return_url,
45- } ) ;
46-
47- return res . status ( 200 ) . json ( { url : portalSession . url } ) ;
48- }
49-
5060 const teamMetadataParsed = teamMetadataSchema . safeParse ( team . metadata ) ;
5161
5262 if ( ! teamMetadataParsed . success ) {
@@ -71,10 +81,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
7181
7282 if ( ! customerId ) return res . status ( 400 ) . json ( { message : "CustomerId not found in stripe" } ) ;
7383
74- const stripeSession = await stripe . billingPortal . sessions . create ( {
75- customer : customerId ,
76- return_url,
77- } ) ;
84+ const billingPortalUrl = await getBillingPortalUrl ( customerId , return_url ) ;
7885
79- res . redirect ( 302 , stripeSession . url ) ;
86+ res . redirect ( 302 , billingPortalUrl ) ;
8087}
0 commit comments