General
Configuration
Billing Configuration
Configure plans, pricing, and credit packages.
The billing configuration file (config/billing.config.ts) contains settings for billing features, subscription plans, pricing, and credit packages for AI features.
Configuration File
The billing configuration is extensive and includes:
- Billing settings: Enable/disable billing, default currency
- Plans: Subscription plans with features, limits, and pricing
- Credit packages: One-time credit purchases for AI features
- Credit costs: Per-model pricing for AI usage
config/billing.config.ts
import { env } from '@/lib/env';
export const billingConfig = {
// Enable/disable billing feature
enabled: true,
// Default currency
defaultCurrency: 'usd',
// Plans configuration
plans: {
// Free tier - no Stripe price needed
free: {
id: 'free',
name: 'Free',
description: 'Get started with basic features',
isFree: true,
features: [
'Up to 3 team members',
'Basic analytics',
'Community support',
'1 GB storage'
],
limits: {
maxMembers: 3,
maxStorage: 1 // GB
}
},
// Pro plan - main paid tier
pro: {
id: 'pro',
name: 'Pro',
description: 'For growing teams',
recommended: true,
features: [
'Unlimited team members',
'Advanced analytics',
'Priority support',
'100 GB storage',
'Custom integrations',
'API access'
],
limits: {
maxMembers: -1, // unlimited
maxStorage: 100 // GB
},
prices: [
{
id: 'pro_monthly',
stripePriceId: env.NEXT_PUBLIC_STRIPE_PRICE_PRO_MONTHLY ?? '',
type: 'recurring',
interval: 'month',
intervalCount: 1,
amount: 2900, // $29.00 in cents
currency: 'usd',
seatBased: true, // Per-seat pricing
trialDays: 14
},
{
id: 'pro_yearly',
stripePriceId: env.NEXT_PUBLIC_STRIPE_PRICE_PRO_YEARLY ?? '',
type: 'recurring',
interval: 'year',
intervalCount: 1,
amount: 27800, // $278.00 in cents
currency: 'usd',
seatBased: true,
trialDays: 14
}
]
},
// Lifetime deal - one-time order
lifetime: {
id: 'lifetime',
name: 'Lifetime',
description: 'Pay once, use forever',
features: [
'All Pro features',
'Lifetime updates',
'Priority support for 1 year',
'100 GB storage'
],
limits: {
maxMembers: -1,
maxStorage: 100
},
prices: [
{
id: 'lifetime_once',
stripePriceId: env.NEXT_PUBLIC_STRIPE_PRICE_LIFETIME ?? '',
type: 'one_time',
amount: 49900, // $499.00 in cents
currency: 'usd'
}
]
}
}
} satisfies BillingConfig;Configuration Options
Billing Settings
enabled: Enable/disable billing feature (default:true)defaultCurrency: Default currency for pricing (default:"usd")
Plans
Each plan in the plans object has:
id: Unique identifier for the planname: Display namedescription: Plan descriptionfeatures: Array of feature stringslimits: Plan limits (members, storage)prices: Array of price configurations
Plan Types
- Free plans: Set
isFree: true, no prices needed - Paid plans: Include
pricesarray with Stripe price IDs - Enterprise plans: Set
isEnterprise: true, typically no prices (contact sales)
Price Configuration
Each price has:
id: Unique price identifierstripePriceId: Stripe Price ID from your Stripe dashboardtype:"recurring"or"one_time"amount: Price in centscurrency: Currency codeinterval: For recurring:"month","year","week", or"day"intervalCount: Number of intervalsseatBased: Whether pricing is per-seat (optional)trialDays: Trial period in days (optional)
Credit Packages
Credit packages are configured separately for one-time purchases:
config/billing.config.ts
export const creditPackages = [
{
id: 'credits_starter',
name: 'Starter',
description: 'Great for trying out AI features',
credits: 10_000,
bonusCredits: 0,
priceAmount: 999, // $9.99 in cents
currency: 'usd',
stripePriceId: env.NEXT_PUBLIC_STRIPE_PRICE_CREDITS_STARTER ?? '',
popular: false
},
{
id: 'credits_basic',
name: 'Basic',
description: 'For regular AI usage',
credits: 50_000,
bonusCredits: 5_000, // 10% bonus
priceAmount: 3999, // $39.99
currency: 'usd',
stripePriceId: env.NEXT_PUBLIC_STRIPE_PRICE_CREDITS_BASIC ?? '',
popular: true
}
];Credit Costs
Credit costs define pricing per AI model:
config/billing.config.ts
export const creditCosts = {
'gpt-4o-mini': {
input: 1, // credits per 1K input tokens
output: 6 // credits per 1K output tokens
},
'gpt-4o': {
input: 25,
output: 100
}
// ... more models
} as const;Use Cases
Add a New Plan
To add a new subscription plan:
config/billing.config.ts
export const billingConfig = {
// ... other config
plans: {
// ... existing plans
business: {
id: 'business',
name: 'Business',
description: 'For larger teams',
features: [
'Everything in Pro',
'Advanced security',
'Dedicated support',
'500 GB storage'
],
limits: {
maxMembers: -1,
maxStorage: 500
},
prices: [
{
id: 'business_monthly',
stripePriceId: env.NEXT_PUBLIC_STRIPE_PRICE_BUSINESS_MONTHLY ?? '',
type: 'recurring',
interval: 'month',
intervalCount: 1,
amount: 9900, // $99.00
currency: 'usd',
seatBased: true
}
]
}
}
};Disable Billing
To disable billing entirely:
config/billing.config.ts
export const billingConfig = {
enabled: false
// ... other config
};Add Enterprise Plan
To add an enterprise plan (contact sales):
config/billing.config.ts
export const billingConfig = {
// ... other config
plans: {
// ... existing plans
enterprise: {
id: 'enterprise',
name: 'Enterprise',
description: 'For large organizations',
isEnterprise: true,
features: [
'Everything in Pro',
'Dedicated account manager',
'Custom SLA',
'Unlimited storage',
'SSO / SAML'
],
limits: {
maxMembers: -1,
maxStorage: -1
}
}
}
};Type Definitions
The configuration uses TypeScript types for type safety:
config/billing.config.ts
export type PriceConfig = {
id: string;
stripePriceId: string;
amount: number;
currency: string;
} & (
| {
type: 'recurring';
interval: 'month' | 'year' | 'week' | 'day';
intervalCount: number;
seatBased?: boolean;
trialDays?: number;
}
| {
type: 'one_time';
}
);
export type PlanLimits = {
maxMembers: number; // -1 for unlimited
maxStorage: number; // in GB, -1 for unlimited
};
export type Plan = FreePlan | PaidPlan | EnterprisePlan;
export type BillingConfig = {
enabled: boolean;
defaultCurrency: string;
plans: Record<string, Plan>;
};Using the Configuration
Import and use the configuration in your code:
lib/billing/plans.ts
import { billingConfig } from '@/config/billing.config';
export function getPlanById(planId: string) {
return billingConfig.plans[planId];
}
export function getAllPlans() {
return Object.values(billingConfig.plans);
}lib/billing/credits.ts
import { creditCosts, creditPackages } from '@/config/billing.config';
export function getCreditPackageById(id: string) {
return creditPackages.find((pkg) => pkg.id === id);
}
export function calculateCreditsForModel(
modelId: string,
inputTokens: number,
outputTokens: number
) {
const costs = creditCosts[modelId as keyof typeof creditCosts];
const inputCost = Math.ceil((inputTokens / 1000) * costs.input);
const outputCost = Math.ceil((outputTokens / 1000) * costs.output);
return inputCost + outputCost;
}Next Steps
For more information on billing, see: