Workspace Subscription
What it is
The Workspace Subscription system tracks subscription end dates for each workspace and manages access control based on subscription status. Workspaces receive warnings before subscription expiration and are blocked from accessing the system when subscriptions expire.
Who it's for
Workspace Owner
Access & Scope
| Property | Value |
|---|---|
| Module | workspace-subscription |
| Personas | workspace-owner |
| Scope | Workspace-level |
| UI Location | Dashboard (banner), Subscription Renewal Page |
| Status | active |
UI Location
- Warning Banner: Appears at the top of the dashboard when subscription is within 10 days of expiration
- Expired Page: Redirected to
/subscription/expiredwhen subscription has expired - Select Plan Page: Accessible at
/subscription/select-planfor choosing a subscription plan - Renewal Page: Accessible at
/subscription/renewfor subscription renewal with period selection
How it works
The Workspace Subscription system manages subscription lifecycle through several components:
1. Subscription Initialization
- When a new workspace is created, the subscription end date is automatically calculated based on the plan's trial period
- Formula:
subscriptionEndDate = createdAt + plan.trialPeriodDays - If the plan has no trial period, the subscription end date is set to the creation date (workspace starts with an expired subscription, requiring immediate renewal)
2. Subscription States
The system recognizes three subscription states:
- Active: Subscription is valid and more than 10 days remain until expiration
- Warning: Subscription is valid but 10 days or less remain until expiration
- Expired: Subscription end date has passed
3. Access Control
- Active State: Full access to all workspace features
- Warning State: Full access with a warning banner displayed at the top of the dashboard
- Expired State: Access is blocked, redirects to the subscription expired page
4. Warning System
- 10-Day Warning: When 10 days or less remain until expiration, a warning banner is displayed
- Email Notification: An automated email is sent when the subscription enters the warning state (10 days remaining)
- Banner Display: The warning banner appears on all dashboard pages, showing:
- Number of days remaining
- Link to renewal page
5. Plan Selection
Before renewing a subscription, workspace owners can choose from available plans:
- Navigate to the Select Plan page at
/subscription/select-plan - View all available subscription plans (excluding the free plan)
- Each plan displays:
- Plan name and description
- Available billing periods (monthly, quarterly, semiannual, annual)
- Prices for each period
- Plan features
- Select a plan to proceed to the renewal page
- The selected plan ID is passed to the renewal page via URL query parameter
Note: If the current plan is "free", users are automatically redirected to the select plan page when attempting to renew.
6. Subscription Renewal
Workspace owners can renew their subscription through a multi-step process:
Step 1: Plan Selection (if needed)
- If changing plans or on free plan, select a plan from the plan selection page
- If renewing current plan, proceed directly to renewal page
Step 2: Period Selection
Each plan supports multiple billing periods with different pricing:
- Monthly: 30 days - Best for short-term commitments
- Quarterly: 90 days (3 months) - Balanced option
- Semiannual: 180 days (6 months) - Mid-term commitment
- Annual: 365 days (1 year) - Long-term commitment with potential savings
The renewal page displays:
- All available periods for the selected plan
- Original price for each period
- Discounted price (if workspace has a discount percentage applied)
- Discount percentage indicator (if applicable)
- Currency code (USD, ILS, JOD, EUR, etc.)
Step 3: Payment Method Selection
Choose between two payment methods:
Method 1: WhatsApp Payment
- Select "WhatsApp" as payment method
- Click the "Open WhatsApp" button
- This opens WhatsApp with a pre-filled message to the support team
- After payment is confirmed, an admin manually updates the subscription end date
Method 2: Card Payment (Mock)
- Select "Card" as payment method
- Fill in card details:
- Cardholder name
- Card number (formatted with spaces)
- Expiry date (MM/YY format)
- CVV
- Submit the form
- The system automatically extends the subscription based on the selected period:
- Monthly: +30 days
- Quarterly: +90 days
- Semiannual: +180 days
- Annual: +365 days
- Success message is displayed, and the user is redirected to the dashboard
Note: The card payment form is currently a mock implementation. All card details are accepted, and the payment is processed automatically.
Renewal Flow Restrictions
- Trial Period Active: If the trial period hasn't ended yet (and user didn't come from select-plan with a new plan), renewal is blocked until trial expires
- Free Plan: Cannot renew free plan - must select a paid plan first
- Period Required: Must select a billing period before proceeding with payment
7. Discount System
Workspaces can have a discount percentage applied to subscription prices:
- Discount Range: 0-100% (set by administrators)
- Application: Discount is automatically applied to all plan prices during renewal
- Display:
- Original price shown with strikethrough
- Discounted price displayed prominently
- Discount percentage shown as a badge
- Calculation:
discountedPrice = originalPrice × (1 - discountPercentage / 100)
Example: If a plan costs $100/month and workspace has 20% discount:
- Original:
$100.00 - Discounted: $80.00
- Badge: "خصم 20%"
8. Admin Subscription Management
Administrators can extend workspace subscriptions from the admin dashboard:
- Navigate to the workspace detail page
- Find the "Subscription Management" section
- Use the extend subscription form:
- Enter the number of days or months to extend
- Select the unit (days or months)
- The form shows:
- Current subscription end date
- New subscription end date (calculated preview)
- Click "Extend Subscription"
- The subscription end date is updated immediately
Features
Warning Banner
- Displays on all dashboard pages when subscription is within warning threshold
- Shows days remaining until expiration
- Provides direct link to renewal page
- Styled with warning colors (amber/yellow)
Subscription Expired Page
- Full-screen page blocking access to the workspace
- Clear message explaining that subscription has expired
- Link to renewal page
- Link to return to home page
Select Plan Page
- Displays all available subscription plans (excluding free plan)
- Shows plan features, pricing, and available billing periods
- Plan selection navigates to renewal page with selected plan ID
- Current plan indicator (if applicable)
- Responsive grid layout for plan comparison
Subscription Renewal Page
- Plan Display: Shows selected plan name and details
- Period Selection: Radio button interface for choosing billing period
- Monthly, Quarterly, Semiannual, Annual options
- Price display with currency
- Discount indicator (if applicable)
- Original vs. discounted price comparison
- Payment Method Selection: Choose between WhatsApp or Card payment
- Card Payment Form: Mock implementation with card details input
- WhatsApp Integration: Pre-filled message with direct link
- Success State: Confirmation message after successful renewal
- Automatic Redirect: Redirects to dashboard after 3 seconds
- Change Plan Button: Option to go back and select a different plan
Admin Subscription Management
- View subscription end date in workspace list and detail pages
- Extend subscription by days or months
- Preview new subscription end date before confirmation
- Immediate update after extension
Subscription End Date Calculation
Initial Calculation (Workspace Creation)
subscriptionEndDate = createdAt + plan.trialPeriodDays
Extension Calculation
By Days
newEndDate = currentEndDate + days
By Months
newEndDate = currentEndDate + months
Renewal Calculation (Card Payment)
The renewal calculation depends on the selected billing period:
// Period-based calculation
switch (period) {
case 'monthly':
newEndDate = currentEndDate + 30 days
case 'quarterly':
newEndDate = currentEndDate + 90 days
case 'semiannual':
newEndDate = currentEndDate + 180 days
case 'annual':
newEndDate = currentEndDate + 365 days
default:
newEndDate = currentEndDate + 30 days (monthly fallback)
}
Note: If no period is specified, defaults to monthly (30 days).
Email Notifications
Subscription Warning Email
- Trigger: When subscription enters warning state (10 days remaining)
- Frequency: Sent once (tracked by
subscriptionWarningSentAtfield) - Content:
- Workspace name
- Subscription end date (formatted)
- Days remaining
- Renewal link (optional)
API Endpoints
Client Endpoints
-
GET /v1/client/plans- Get all available plans with price periods- Query:
locale(optional, for localized plan names) - Response:
{ plans: Plan[] }where each plan includes:id,name,slug,descriptionpricePeriods: Array of{ period: 'monthly'|'quarterly'|'semiannual'|'annual', amountCents: number, currencyCode: string }features,flags,trialPeriodDays
- Query:
-
POST /v1/workspace/:workspaceId/subscription/renew- Body:
{ paymentMethod: 'whatsapp' | 'card', period?: 'monthly' | 'quarterly' | 'semiannual' | 'annual', cardDetails?: { cardNumber, expiryDate, cvv, cardholderName } } - Response:
{ success: boolean, newSubscriptionEndDate?: string, message: string }
- Body:
Admin Endpoints
-
PATCH /v1/admin/workspaces/:workspaceId/subscription/extend- Body:
{ days?: number, months?: number } - Response:
{ workspace: WorkspaceSummary, newSubscriptionEndDate: string }
- Body:
-
PATCH /v1/admin/workspaces/:workspaceId/discount- Body:
{ discountPercentage: number | null }(0-100, or null to remove) - Response:
{ workspace: WorkspaceSummary, message: string }
- Body:
Technical Details
Database Fields
Workspace Model:
subscriptionEndDate: Date | null- The date when the subscription expiressubscriptionWarningSentAt: Date | null- Timestamp when warning email was sent (prevents duplicate emails)discountPercentage: number | null- Discount percentage (0-100) applied to subscription prices
Plan Model:
pricePeriods: PlanPricePeriod[]- Array of pricing periods, each containing:period: 'monthly' | 'quarterly' | 'semiannual' | 'annual'amountCents: number- Price in centscurrencyCode: string- Currency code (USD, ILS, JOD, EUR, etc.)
Middleware
checkWorkspaceSubscriptionmiddleware is applied to all client routes withworkspaceIdparameter- Blocks requests with 403 Forbidden if subscription has expired
- Allows requests to proceed if subscription is active or in warning state
Background Jobs (Optional)
- A scheduled job can be set up to periodically check for subscriptions entering the warning state
- The
checkAndSendWarnings()function insubscription-notification.service.tscan be called by a cron job
Subscription Periods
The system supports four billing periods, each with different pricing:
| Period | Duration | Days Added on Renewal | Use Case |
|---|---|---|---|
| Monthly | 30 days | +30 days | Short-term, flexible commitment |
| Quarterly | 90 days (3 months) | +90 days | Balanced option for medium-term users |
| Semiannual | 180 days (6 months) | +180 days | Mid-term commitment with better value |
| Annual | 365 days (1 year) | +365 days | Long-term commitment, often with best pricing |
Period Selection
- Plans can have one or more available periods
- Each period has its own price (in cents) and currency
- Users must select a period before completing payment
- Period selection affects the subscription extension duration
Price Periods in Plans
Each plan can define multiple price periods:
{
period: 'monthly',
amountCents: 4900, // $49.00
currencyCode: 'USD'
}
Plans can have different prices for different periods, allowing for:
- Discounted annual pricing
- Regional currency support
- Flexible pricing strategies
Discount System
Workspace-Level Discounts
Administrators can set a discount percentage (0-100%) for any workspace:
- Automatic Application: Discount is automatically applied to all plan prices during renewal
- Visual Feedback:
- Original price shown with strikethrough
- Discounted price displayed prominently
- Discount percentage badge
- Calculation: Applied to the base price before display
- Removal: Set to
nullto remove discount
Example Discount Flow
- Plan has monthly price: $100.00
- Workspace has discount: 20%
- Display shows:
$100.00(original, strikethrough)- $80.00 (discounted, bold)
- "خصم 20%" badge
Related Features
- Workspace Settings: General workspace configuration
- Plans: Subscription plans, price periods, and trial periods
- Email Notifications: Subscription warning emails
- Admin Workspace Management: Admin tools for subscription management and discount configuration
- Payment Settings: Configuration for enabled payment methods (card, WhatsApp)