feat(cloud): enable upgrading new and existing workspaces onto team/pro
This commit is contained in:
@@ -20,13 +20,13 @@ const workspaceSlugSchema = z
|
|||||||
interface CheckoutSessionRequest {
|
interface CheckoutSessionRequest {
|
||||||
successUrl: string;
|
successUrl: string;
|
||||||
cancelUrl: string;
|
cancelUrl: string;
|
||||||
|
plan: "team" | "pro";
|
||||||
billing?: string;
|
billing?: string;
|
||||||
workspacePublicId?: string;
|
workspacePublicId?: string;
|
||||||
slug?: string;
|
slug?: string;
|
||||||
workspaceName?: string;
|
workspaceName?: string;
|
||||||
workspaceDescription?: string;
|
workspaceDescription?: string;
|
||||||
workspaceSlug?: string;
|
workspaceSlug?: string;
|
||||||
plan?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withRateLimit(
|
export default withRateLimit(
|
||||||
@@ -38,7 +38,6 @@ export default withRateLimit(
|
|||||||
return res.status(405).json({ error: "Method not allowed" });
|
return res.status(405).json({ error: "Method not allowed" });
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
const { user, db } = await createNextApiContext(req);
|
const { user, db } = await createNextApiContext(req);
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
@@ -49,6 +48,7 @@ export default withRateLimit(
|
|||||||
const {
|
const {
|
||||||
successUrl,
|
successUrl,
|
||||||
cancelUrl,
|
cancelUrl,
|
||||||
|
plan,
|
||||||
billing,
|
billing,
|
||||||
workspacePublicId,
|
workspacePublicId,
|
||||||
slug,
|
slug,
|
||||||
@@ -57,7 +57,7 @@ export default withRateLimit(
|
|||||||
workspaceSlug,
|
workspaceSlug,
|
||||||
} = body;
|
} = body;
|
||||||
|
|
||||||
if (!successUrl || !cancelUrl) {
|
if (!successUrl || !cancelUrl || !plan) {
|
||||||
return res.status(400).json({ error: "Missing required fields" });
|
return res.status(400).json({ error: "Missing required fields" });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ export default withRateLimit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const subscription = await subscriptionRepo.create(db, {
|
const subscription = await subscriptionRepo.create(db, {
|
||||||
plan: "pro",
|
plan: plan,
|
||||||
referenceId: workspacePublicId,
|
referenceId: workspacePublicId,
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
stripeCustomerId: user.stripeCustomerId ?? "",
|
stripeCustomerId: user.stripeCustomerId ?? "",
|
||||||
@@ -115,9 +115,9 @@ export default withRateLimit(
|
|||||||
|
|
||||||
const isTeam = body.plan === "team";
|
const isTeam = body.plan === "team";
|
||||||
const annualPriceId = isTeam
|
const annualPriceId = isTeam
|
||||||
? (process.env.STRIPE_TEAM_PLAN_ANNUAL_PRICE_ID ??
|
? (process.env.STRIPE_TEAM_PLAN_YEARLY_PRICE_ID ??
|
||||||
process.env.STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID)
|
process.env.STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID)
|
||||||
: (process.env.STRIPE_PRO_PLAN_ANNUAL_PRICE_ID ??
|
: (process.env.STRIPE_PRO_PLAN_YEARLY_PRICE_ID ??
|
||||||
process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID);
|
process.env.STRIPE_PRO_PLAN_MONTHLY_PRICE_ID);
|
||||||
const monthlyPriceId = isTeam
|
const monthlyPriceId = isTeam
|
||||||
? process.env.STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID
|
? process.env.STRIPE_TEAM_PLAN_MONTHLY_PRICE_ID
|
||||||
@@ -141,14 +141,11 @@ export default withRateLimit(
|
|||||||
...(workspaceName && { workspaceName }),
|
...(workspaceName && { workspaceName }),
|
||||||
...(workspaceDescription && { workspaceDescription }),
|
...(workspaceDescription && { workspaceDescription }),
|
||||||
...(subscriptionId && { subscriptionId: String(subscriptionId) }),
|
...(subscriptionId && { subscriptionId: String(subscriptionId) }),
|
||||||
plan: body.plan ?? "pro",
|
plan: plan,
|
||||||
isNewWorkspace: workspaceName ? "true" : "false",
|
isNewWorkspace: workspaceName ? "true" : "false",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.status(200).json({ url: session.url });
|
return res.status(200).json({ url: session.url });
|
||||||
} catch (error) {
|
|
||||||
return res.status(500).json({ error: "Error creating checkout session" });
|
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -20,8 +20,11 @@ export function withApiLogging(
|
|||||||
const requestId = randomUUID();
|
const requestId = randomUUID();
|
||||||
const route = req.url?.split("?")[0] ?? "unknown";
|
const route = req.url?.split("?")[0] ?? "unknown";
|
||||||
const input = {
|
const input = {
|
||||||
...(req.query && Object.keys(req.query).length > 0 && { query: req.query }),
|
...(req.query &&
|
||||||
...(req.body && typeof req.body === "object" && Object.keys(req.body).length > 0 && { body: req.body }),
|
Object.keys(req.query).length > 0 && { query: req.query }),
|
||||||
|
...(req.body &&
|
||||||
|
typeof req.body === "object" &&
|
||||||
|
Object.keys(req.body).length > 0 && { body: req.body }),
|
||||||
};
|
};
|
||||||
|
|
||||||
let statusCode = 200;
|
let statusCode = 200;
|
||||||
@@ -41,7 +44,16 @@ export function withApiLogging(
|
|||||||
// unauthenticated or auth unavailable
|
// unauthenticated or auth unavailable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let handlerError: unknown;
|
||||||
|
try {
|
||||||
await handler(req, res);
|
await handler(req, res);
|
||||||
|
} catch (err) {
|
||||||
|
handlerError = err;
|
||||||
|
statusCode = 500;
|
||||||
|
if (!res.headersSent) {
|
||||||
|
res.status(500).json({ error: "Internal server error" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const duration = Date.now() - start;
|
const duration = Date.now() - start;
|
||||||
const meta = {
|
const meta = {
|
||||||
@@ -53,6 +65,10 @@ export function withApiLogging(
|
|||||||
...(isCloud && email && { email }),
|
...(isCloud && email && { email }),
|
||||||
...(Object.keys(input).length > 0 && { input }),
|
...(Object.keys(input).length > 0 && { input }),
|
||||||
status: statusCode,
|
status: statusCode,
|
||||||
|
...(handlerError instanceof Error && {
|
||||||
|
error: handlerError.message,
|
||||||
|
stack: handlerError.stack,
|
||||||
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (statusCode < 400) {
|
if (statusCode < 400) {
|
||||||
|
|||||||
Reference in New Issue
Block a user