feat: Implement A4 invoice layout and hide Label for virtual orders
Invoice: - Enhanced A4-ready layout with proper structure - Store header with invoice number - Billing/shipping address sections - Styled items table with alternating rows - Totals summary with conditional display - Thank you footer Label: - Label button now hidden for virtual-only orders - Uses existing isVirtualOnly detection Print CSS: - Added @page A4 size directive - Print-color-adjust for background colors - 20mm padding for proper margins Documentation: - Updated subscription module plan (comprehensive) - Updated affiliate module plan (comprehensive) - Created shipping label standardization plan
This commit is contained in:
191
.agent/plans/subscription-module.md
Normal file
191
.agent/plans/subscription-module.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user