5.7 KiB
Subscription Module Comprehensive Audit Report
Date: 2026-01-29
Scope: Full module trace including orders, notifications, permissions, payment gateway integration, auto/manual renewal, early renewal
Executive Summary
I performed a comprehensive audit of the subscription module and implemented fixes for all Critical and Warning issues.
Total Issues Found: 11
- CRITICAL: 2 ✅ FIXED
- WARNING: 5 ✅ FIXED
- INFO: 4 (No action required)
Fixes Implemented
✅ Critical Issue #1: handle_renewal_success Now Sets Status to Active
File: [SubscriptionManager.php](file:///Users/dwindown/Local Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Modules/Subscription/SubscriptionManager.php#L708-L719)
Change:
$wpdb->update(
self::$table_subscriptions,
[
+ 'status' => 'active',
'next_payment_date' => $next_payment,
'last_payment_date' => current_time('mysql'),
'failed_payment_count' => 0,
],
['id' => $subscription_id],
- ['%s', '%s', '%d'],
+ ['%s', '%s', '%s', '%d'],
['%d']
);
✅ Critical Issue #2: Added Renewal Reminder Handler
File: [SubscriptionModule.php](file:///Users/dwindown/Local Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Modules/Subscription/SubscriptionModule.php)
Changes:
- Added action hook registration:
add_action('woonoow/subscription/renewal_reminder', [__CLASS__, 'on_renewal_reminder'], 10, 1);
- Added event registration:
$events['subscription_renewal_reminder'] = [
'id' => 'subscription_renewal_reminder',
'label' => __('Subscription Renewal Reminder', 'woonoow'),
// ...
];
- Added handler method:
public static function on_renewal_reminder($subscription)
{
if (!$subscription || !isset($subscription->id)) {
return;
}
self::send_subscription_notification('subscription_renewal_reminder', $subscription->id);
}
✅ Warning Issue #3: Added Duplicate Renewal Order Prevention
File: [SubscriptionManager.php::renew](file:///Users/dwindown/Local Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Modules/Subscription/SubscriptionManager.php#L511-L535)
Change: Before creating a new renewal order, the system now checks for existing pending orders:
$existing_pending = $wpdb->get_row($wpdb->prepare(
"SELECT so.order_id FROM ... WHERE ... AND p.post_status IN ('wc-pending', 'pending', 'wc-on-hold', 'on-hold')",
$subscription_id
));
if ($existing_pending) {
return ['success' => true, 'order_id' => (int) $existing_pending->order_id, 'status' => 'existing'];
}
Also allowed on-hold subscriptions to renew (in addition to active).
✅ Warning Issue #4: Removed Duplicate Route Registration
File: [CheckoutController.php](file:///Users/dwindown/Local Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Api/CheckoutController.php)
Change: Removed duplicate /checkout/pay-order/{id} route registration (was registered twice).
✅ Warning Issue #5: Added has_settings to Subscription Module
File: [ModuleRegistry.php](file:///Users/dwindown/Local Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Core/ModuleRegistry.php#L64-L78)
Change:
'subscription' => [
// ...
'default_enabled' => false,
+ 'has_settings' => true,
'features' => [...],
],
Now subscription settings will appear in Admin SPA > Settings > Modules > Subscription.
✅ Issue #10: Replaced Transient Tracking with Database Column
Files:
- [SubscriptionManager.php](file:///Users/dwindown/Local Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Modules/Subscription/SubscriptionManager.php) - Added
reminder_sent_atcolumn - [SubscriptionScheduler.php](file:///Users/dwindown/Local Sites/woonoow/app/public/wp-content/plugins/woonoow/includes/Modules/Subscription/SubscriptionScheduler.php) - Updated to use database column
Changes:
- Added column to table schema:
reminder_sent_at DATETIME DEFAULT NULL,
- Updated scheduler logic:
// Query now includes:
AND (reminder_sent_at IS NULL OR reminder_sent_at < last_payment_date OR ...)
// After sending:
$wpdb->update($table, ['reminder_sent_at' => current_time('mysql')], ...);
Remaining INFO Issues (No Action Required)
| # | Issue | Status |
|---|---|---|
| 6 | Payment gateway integration is placeholder only | Phase 2 - needs separate adapter classes |
| 7 | ThankYou page doesn't display subscription info | Enhancement for future |
| 9 | "Renew Early" only for active subscriptions | Confirmed as acceptable UX |
| 11 | API permissions correctly configured | Verified ✓ |
Summary of Files Modified
| File | Changes |
|---|---|
SubscriptionManager.php |
• Fixed handle_renewal_success to set status• Added duplicate order prevention • Added reminder_sent_at column |
SubscriptionModule.php |
• Added renewal reminder hook • Added event registration • Added handler method |
SubscriptionScheduler.php |
• Replaced transient tracking with database column |
CheckoutController.php |
• Removed duplicate route registration |
ModuleRegistry.php |
• Added has_settings => true for subscription |
Database Migration Note
Important
The
reminder_sent_atcolumn has been added to the subscriptions table schema. SincedbDelta()is used, it should be added automatically on next module re-enable or table check. However, for existing installations, you may need to:
- Disable and re-enable the Subscription module in Admin SPA, OR
- Run:
ALTER TABLE wp_woonoow_subscriptions ADD COLUMN reminder_sent_at DATETIME DEFAULT NULL;