129 lines
3.1 KiB
TypeScript
129 lines
3.1 KiB
TypeScript
export type BillingPlan = {
|
|
id?: string;
|
|
name: string;
|
|
slug: string;
|
|
description: string;
|
|
priceMonthly: number;
|
|
currency: string;
|
|
stripeProductId?: string;
|
|
stripePriceId?: string;
|
|
messageLimit?: number | null;
|
|
agentLimit?: number | null;
|
|
isFeatured?: boolean;
|
|
isActive?: boolean;
|
|
features: string[];
|
|
};
|
|
|
|
export type BillingSubscription = {
|
|
id: string;
|
|
status: string;
|
|
stripeCustomerId?: string;
|
|
stripeSubscriptionId?: string;
|
|
currentPeriodStart?: string;
|
|
currentPeriodEnd?: string;
|
|
cancelAtPeriodEnd?: boolean;
|
|
plan: BillingPlan | null;
|
|
};
|
|
|
|
export type StripeSettingsPlan = {
|
|
id?: string;
|
|
name: string;
|
|
slug: string;
|
|
stripeProductId?: string;
|
|
stripePriceId?: string;
|
|
};
|
|
|
|
export type StripeSettingsState = {
|
|
stripeSecretKey: string;
|
|
stripeSecretKeyPreview: string;
|
|
stripeSecretKeySource: string;
|
|
stripeWebhookSecret: string;
|
|
stripeWebhookSecretPreview: string;
|
|
stripeWebhookSecretSource: string;
|
|
webhookEndpoint: string;
|
|
webhookEvents: string[];
|
|
plans: StripeSettingsPlan[];
|
|
};
|
|
|
|
export const marketingPlans: BillingPlan[] = [
|
|
{
|
|
name: 'Starter',
|
|
slug: 'starter',
|
|
description: 'For solo builders who want a calm workspace and the basics of AI billing.',
|
|
priceMonthly: 19,
|
|
currency: 'usd',
|
|
stripeProductId: 'prod_mock_starter',
|
|
stripePriceId: 'price_mock_starter_monthly',
|
|
messageLimit: 300,
|
|
agentLimit: 3,
|
|
isFeatured: false,
|
|
features: [
|
|
'300 AI messages every month',
|
|
'3 custom agents',
|
|
'Conversation history and export',
|
|
],
|
|
},
|
|
{
|
|
name: 'Pro',
|
|
slug: 'pro',
|
|
description: 'For frequent users who need more messages, more agents, and a stronger daily workflow.',
|
|
priceMonthly: 49,
|
|
currency: 'usd',
|
|
stripeProductId: 'prod_mock_pro',
|
|
stripePriceId: 'price_mock_pro_monthly',
|
|
messageLimit: 1500,
|
|
agentLimit: 10,
|
|
isFeatured: true,
|
|
features: [
|
|
'1,500 AI messages every month',
|
|
'10 custom agents',
|
|
'Priority billing support',
|
|
],
|
|
},
|
|
{
|
|
name: 'Team',
|
|
slug: 'team',
|
|
description: 'For heavier shared use with more throughput and room for longer-running work.',
|
|
priceMonthly: 149,
|
|
currency: 'usd',
|
|
stripeProductId: 'prod_mock_team',
|
|
stripePriceId: 'price_mock_team_monthly',
|
|
messageLimit: 5000,
|
|
agentLimit: 30,
|
|
isFeatured: false,
|
|
features: [
|
|
'5,000 AI messages every month',
|
|
'30 custom agents',
|
|
'Shared workspace billing controls',
|
|
],
|
|
},
|
|
];
|
|
|
|
export function formatBillingPrice(amount: number, currency = 'usd') {
|
|
return new Intl.NumberFormat('en-US', {
|
|
style: 'currency',
|
|
currency: currency.toUpperCase(),
|
|
maximumFractionDigits: 0,
|
|
}).format(amount);
|
|
}
|
|
|
|
export function formatBillingLimit(value: number | null | undefined, label: string) {
|
|
if (!value) {
|
|
return `Unlimited ${label}`;
|
|
}
|
|
|
|
return `${value.toLocaleString()} ${label}`;
|
|
}
|
|
|
|
export function formatBillingDate(value?: string) {
|
|
if (!value) {
|
|
return '';
|
|
}
|
|
|
|
return new Intl.DateTimeFormat('en-US', {
|
|
month: 'short',
|
|
day: 'numeric',
|
|
year: 'numeric',
|
|
}).format(new Date(value));
|
|
}
|