# Subscription Module Plan

## Overview
Recurring product subscriptions with flexible billing, integrated as a core plugin module (like Newsletter/Wishlist/Licensing).

---

## Module Architecture

### Core Features
- **Recurring billing**: Weekly, monthly, yearly, custom intervals
- **Free trials**: X days free before billing starts
- **Sign-up fees**: One-time fee on first subscription
- **Automatic renewals**: Process payment on renewal date
- **Manual renewal**: Allow customers to renew manually
- **Proration**: Calculate prorated amounts on plan changes
- **Pause/Resume**: Allow customers to pause subscriptions

### Product Integration
- Checkbox under "Additional Options": **Enable subscription for this product**
- When enabled, show subscription settings:
  - Billing period (weekly/monthly/yearly/custom)
  - Billing interval (every X periods)
  - Free trial days
  - Sign-up fee
  - Subscription length (0 = unlimited)
- Variable products: Variation-level subscription settings (different durations/prices per variation)

### Integration with Licensing
- Licenses can be bound to subscriptions
- When subscription is active → license is valid
- When subscription expires/cancelled → license is revoked
- Auto-renewal keeps license active

---

## Database Schema

### Table: `woonoow_subscriptions`
```sql
CREATE TABLE woonoow_subscriptions (
  id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  user_id BIGINT UNSIGNED NOT NULL,
  order_id BIGINT UNSIGNED NOT NULL,
  product_id BIGINT UNSIGNED NOT NULL,
  variation_id BIGINT UNSIGNED DEFAULT NULL,
  status ENUM('pending', 'active', 'on-hold', 'cancelled', 'expired', 'pending-cancel') DEFAULT 'pending',
  billing_period ENUM('day', 'week', 'month', 'year') NOT NULL,
  billing_interval INT UNSIGNED DEFAULT 1,
  start_date DATETIME NOT NULL,
  trial_end_date DATETIME DEFAULT NULL,
  next_payment_date DATETIME DEFAULT NULL,
  end_date DATETIME DEFAULT NULL,
  last_payment_date DATETIME DEFAULT NULL,
  payment_method VARCHAR(100) DEFAULT NULL,
  payment_meta LONGTEXT,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  INDEX idx_user_id (user_id),
  INDEX idx_order_id (order_id),
  INDEX idx_status (status),
  INDEX idx_next_payment (next_payment_date)
);
```

### Table: `woonoow_subscription_orders`
Links subscription to renewal orders:
```sql
CREATE TABLE woonoow_subscription_orders (
  id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  subscription_id BIGINT UNSIGNED NOT NULL,
  order_id BIGINT UNSIGNED NOT NULL,
  order_type ENUM('parent', 'renewal', 'switch', 'resubscribe') DEFAULT 'renewal',
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  INDEX idx_subscription (subscription_id),
  INDEX idx_order (order_id)
);
```

---

## Backend Structure

```
includes/Modules/Subscription/
├── SubscriptionModule.php      # Bootstrap, hooks, product meta
├── SubscriptionManager.php     # Core logic
├── SubscriptionScheduler.php   # Cron jobs for renewals
└── SubscriptionSettings.php    # Settings schema

includes/Api/SubscriptionsController.php  # REST endpoints
```

### SubscriptionManager Methods
```php
- create($order, $product, $user)     # Create subscription from order
- renew($subscription_id)              # Process renewal
- cancel($subscription_id, $reason)    # Cancel subscription
- pause($subscription_id)              # Pause subscription
- resume($subscription_id)             # Resume paused subscription
- switch($subscription_id, $new_product) # Switch plan
- get_next_payment_date($subscription) # Calculate next date
- process_renewal_payment($subscription) # Charge payment
```

### Cron Jobs
- `woonoow_process_subscription_renewals`: Run daily, process due renewals
- `woonoow_check_expired_subscriptions`: Mark expired subscriptions

---

## REST API Endpoints

### Admin Endpoints
```
GET    /subscriptions              # List all subscriptions
GET    /subscriptions/{id}         # Get subscription details
PUT    /subscriptions/{id}         # Update subscription
POST   /subscriptions/{id}/cancel  # Cancel subscription
POST   /subscriptions/{id}/renew   # Force renewal
```

### Customer Endpoints
```
GET    /my-subscriptions           # Customer's subscriptions
GET    /my-subscriptions/{id}      # Subscription detail
POST   /my-subscriptions/{id}/cancel   # Request cancellation
POST   /my-subscriptions/{id}/pause    # Pause subscription
POST   /my-subscriptions/{id}/resume   # Resume subscription
```

---

## Admin SPA

### Subscriptions List (`/subscriptions`)
- Table: ID, Customer, Product, Status, Next Payment, Actions
- Filters: Status, Product, Date range
- Actions: View, Cancel, Renew

### Subscription Detail (`/subscriptions/:id`)
- Subscription info card
- Related orders list
- Payment history
- Action buttons: Cancel, Pause, Renew

---

## Customer SPA

### My Subscriptions (`/my-account/subscriptions`)
- List of active/past subscriptions
- Status badges
- Next payment info
- Actions: Cancel, Pause, View

### Subscription Detail
- Product info
- Billing schedule
- Payment history
- Management actions

---

## Settings Schema

```php
return [
  'default_status' => 'active',
  'button_text_subscribe' => 'Subscribe Now',
  'button_text_renew' => 'Renew Subscription',
  'allow_customer_cancel' => true,
  'allow_customer_pause' => true,
  'max_pause_count' => 3,
  'renewal_retry_days' => [1, 3, 5],  // Retry failed payments
  'expire_after_failed_attempts' => 3,
  'send_renewal_reminder' => true,
  'reminder_days_before' => 3,
];
```

---

## Implementation Priority
1. Database tables and SubscriptionManager
2. Product meta fields for subscription settings
3. Order hook to create subscription
4. Renewal cron job
5. Admin SPA list/detail pages
6. Customer SPA pages
7. Integration with Licensing module
