Subscription Service
Overview
The Subscription Service is the central business logic layer for managing user subscriptions throughout their full lifecycle: creation, plan management, cancellation, expiration processing, auto-renewal, and feature gating. It wraps the database query layer with business rules, logging, and plan-specific logic. The service is implemented as an instance-based class with a pre-exported singleton (subscriptionService) for convenient usage.
Architecture
The Subscription Service sits between the API/webhook handlers and the database query layer. It orchestrates subscription state transitions, logs all changes to a history table, and provides plan-based feature access control. It works alongside the Webhook Subscription Service (which handles inbound payment provider events) and the Stripe Products Service (which provides pricing data).
API Routes / Webhooks / Cron Jobs
|
subscription.service.ts (business logic)
|
lib/db/queries (database operations)
|
Database (subscriptions, subscription_history tables)
API Reference
Types
CreateSubscriptionData
interface CreateSubscriptionData {
userId: string;
planId: PaymentPlan;
paymentProvider: PaymentProvider;
subscriptionId: string;
priceId?: string;
customerId?: string;
currency?: string; // Default: 'usd'
amount?: number;
interval?: string; // Default: 'month'
intervalCount?: number; // Default: 1
startDate: Date;
endDate?: Date;
trialStart?: Date;
trialEnd?: Date;
metadata?: any;
}
UpdateSubscriptionData
interface UpdateSubscriptionData {
planId?: string;
status?: string;
endDate?: Date;
amount?: number;
interval?: string;
intervalCount?: number;
priceId?: string;
metadata?: any;
}
Subscription CRUD
createSubscription(data: CreateSubscriptionData): Promise<Subscription>
Creates a new subscription with PENDING status and logs the creation event.
getSubscriptionById(subscriptionId: string): Promise<Subscription | null>
Retrieves a subscription with its associated user data.
getUserActiveSubscription(userId: string): Promise<Subscription | null>
Returns the user's currently active subscription, or null if none exists.
getUserSubscriptions(userId: string): Promise<Subscription[]>
Returns all subscriptions for a user (active, cancelled, expired, etc.).
getSubscriptionByProviderSubscriptionId(paymentProvider: string, subscriptionId: string): Promise<Subscription | null>
Finds a subscription by the external payment provider's subscription ID.
updateSubscription(subscriptionId: string, data: UpdateSubscriptionData): Promise<Subscription | null>
Updates subscription fields. Metadata is JSON-serialized before storage.
cancelSubscription(subscriptionId: string, reason?: string, cancelAtPeriodEnd?: boolean): Promise<Subscription | null>
Cancels a subscription, optionally deferring cancellation to the end of the billing period.
Plan and Feature Access
hasActiveSubscription(userId: string): Promise<boolean>
Returns true if the user has any active subscription.
getUserPlan(userId: string): Promise<string>
Returns the user's current plan ID (e.g., 'free', 'standard', 'premium').
getUserPlanWithExpiration(userId: string): Promise<object>
Returns comprehensive plan details including expiration state, warning period, and formatted warning messages.
Returns:
{
planId: string;
effectivePlan: string; // Actual plan after considering expiration
isExpired: boolean;
expiresAt: Date | null;
daysUntilExpiration: number | null;
isInWarningPeriod: boolean;
canAccessPlanFeatures: boolean;
warningMessage: string | null;
status: string | null;
}
canAccessFeature(userId: string, feature: string): Promise<boolean>
Checks if the user's current plan includes a specific feature.
Feature hierarchy:
| Plan | Features |
|---|---|
| Free | basic_access |
| Standard | basic_access, advanced_features, pro_features, priority_support |
| Premium | All Standard features + premium_features, enterprise_features |
getPlanDisplayName(planId: string): string
Returns a human-readable plan name from the PAYMENT_PLAN_NAMES constant map.
getPlanLimits(planId: string): Record<string, number>
Returns numerical limits for a plan.
| Limit | Free | Standard | Premium |
|---|---|---|---|
| Projects | 1 | 5 | 100 |
| Storage (MB) | 100 | 1,000 | 50,000 |
| Users | 1 | 5 | 100 |
| API Calls | 1,000 | 10,000 | 500,000 |