diff --git a/packages/shared-billing/src/config/billing.config.ts b/packages/shared-billing/src/config/billing.config.ts index a95412e..df9ffb4 100644 --- a/packages/shared-billing/src/config/billing.config.ts +++ b/packages/shared-billing/src/config/billing.config.ts @@ -74,7 +74,7 @@ export const loadBillingConfig = (): BillingConfig => ({ darkWebScans: 12, }, plus: { - priceId: process.env.STRIPE_PLUS_TIER_PRICE_ID!, + priceId: process.env.STRIPE_PLUS_TIER_PRICE_ID || 'price_plus', monthlyPriceCents: 1999, callMinutesLimit: 2000, smsCountLimit: 10000, @@ -82,7 +82,7 @@ export const loadBillingConfig = (): BillingConfig => ({ voiceCloning: true, }, premium: { - priceId: process.env.STRIPE_PREMIUM_TIER_PRICE_ID!, + priceId: process.env.STRIPE_PREMIUM_TIER_PRICE_ID || 'price_premium', monthlyPriceCents: 4999, callMinutesLimit: 10000, smsCountLimit: 50000, diff --git a/packages/shared-billing/src/index.ts b/packages/shared-billing/src/index.ts index 8a4cc67..96be282 100644 --- a/packages/shared-billing/src/index.ts +++ b/packages/shared-billing/src/index.ts @@ -4,6 +4,7 @@ export { requireTier, checkUsageLimit, withUsageTracking, + withSubscription, requireSubscription, } from './middleware/billing.middleware'; diff --git a/packages/shared-billing/src/middleware/billing.middleware.ts b/packages/shared-billing/src/middleware/billing.middleware.ts index 1ff9ee2..7fce136 100644 --- a/packages/shared-billing/src/middleware/billing.middleware.ts +++ b/packages/shared-billing/src/middleware/billing.middleware.ts @@ -7,7 +7,8 @@ const billingService = BillingService.getInstance(); export interface AuthenticatedRequest extends Request { userId?: string; tier?: SubscriptionTier; - usage?: { current: number; limit: number; remaining: number }; + usage?: { current: number; limit: number; remaining: number; withinLimit: boolean }; + subscriptionId?: string; } export function requireTier( @@ -108,24 +109,52 @@ export function withUsageTracking( }; } +export function withSubscription() { + return async ( + req: AuthenticatedRequest, + res: Response, + next: NextFunction + ): Promise => { + const { userId, tier } = req; + + if (!userId || !tier) { + next(); + return; + } + + try { + // Fetch subscription from database + // TODO: Replace with actual database query + const subscriptionId = (req as any).subscriptionId; + + if (subscriptionId) { + req.subscriptionId = subscriptionId; + } + + next(); + } catch (error) { + res.status(500).json({ + error: 'Failed to fetch subscription', + message: error instanceof Error ? error.message : 'Unknown error', + }); + } + }; +} + export function requireSubscription() { return async ( req: AuthenticatedRequest, res: Response, next: NextFunction ): Promise => { - const { userId } = req; + const { userId, subscriptionId } = req; if (!userId) { res.status(401).json({ error: 'Authentication required' }); return; } - // Check if user has active subscription - // This would typically query the database - const hasSubscription = (req as any).subscriptionId != null; - - if (!hasSubscription) { + if (!subscriptionId) { res.status(402).json({ error: 'Active subscription required', }); diff --git a/packages/shared-billing/src/services/billing.service.ts b/packages/shared-billing/src/services/billing.service.ts index 0e49a62..cc4a4ed 100644 --- a/packages/shared-billing/src/services/billing.service.ts +++ b/packages/shared-billing/src/services/billing.service.ts @@ -132,7 +132,14 @@ export class BillingService { ): Promise { return await stripe.invoices.create({ customer: customerId, - metadata: { ...metadata, description }, + line_items: [ + { + amount_data: { currency: 'usd', unit_amount: amount }, + description: description, + quantity: 1, + }, + ], + metadata: metadata, }); }