Doctor Subs
Doctor Subs
Description
You don’t always find out a renewal is broken until a customer emails you. Doctor Subs watches your subscriptions in the background and tells you when something is silently wrong, before you hear about it.
For each problem, you get a plain-English explanation, a preview of exactly what the fix will change, and one button to apply it. Every fix is logged and can be undone. If a fix already triggered a real payment, the undo screen says so explicitly.
Built for store owners who run between 20 and 500 active subscriptions and don’t want to read logs or write code.
What it spots
- Subscriptions silently flipped to “manual renewal” by recent WooCommerce bugs, so auto-billing has quietly stopped.
- Active subscriptions with no next payment scheduled – the next charge will never happen.
- A wave of subscriptions all going on hold at once after a product change.
- Customers who paid in Stripe but whose subscription is still showing on hold.
- Subscriptions with a couple of recent failed payments – usually a gateway blip a single retry fixes.
- Subscription totals that no longer match their line items.
What it doesn’t do
- It doesn’t change anything without you clicking. There’s no auto-fix.
- It doesn’t replace dunning, retries, or refunds. For card declines and refunds, use your gateway.
- It doesn’t send your customer data anywhere.
If you’ve ever found out about a broken renewal from a customer instead of from your store, this is for you.
Installation
Automatic
- Plugins > Add New > search “Doctor Subs”
- Install > Activate
Manual
- Download the plugin zip from WordPress.org or GitHub Releases
- Plugins > Add New > Upload Plugin
- Install > Activate
After activation
- WooCommerce > Doctor Subs
- Click Scan my subscriptions
- Review the X-of-Y healthy stat and the two action counters, click into the broken bucket, preview a fix, commit
Screenshots

Dashboard: X-of-Y healthy stat, At risk + Broken counters, search, rule chips, and the Needs attention table with the "Fix all" CTA next to the active filter

Fix preview modal: plain-English narrative, named diff (before -> after), and the "you can undo this" reassurance line

Fix history: per-rule filter chips along the top, plain-English summary per row, individual Revert buttons

Settings: alerts toggle + email recipient, fix-history retention selector, anonymous telemetry opt-in

Detection rules: six rule cards with on/off toggles plus Detects + Fix descriptions for every rule
Faq
No. The plugin never mutates your data without an explicit Fix click. Every change shows a preview first and lands in the Fix history with a Revert button. The scanner only detects; the merchant decides.
The revert confirm explicitly tells you: the re-scheduled payment has already charged the customer, reverting will undo the status change but will NOT refund. If a refund is needed, handle it in the related WooCommerce order.
Yes. The Manual-renewal drift rule looks for active subs whose _requires_manual_renewal flag is set despite a working Stripe customer/source meta on file. It clears the flag in both the orders table and postmeta (belt-and-braces against the HPOS sync gap), re-stamps next_payment if past-due, and schedules a fresh renewal so WCS bills automatically again.
No. Doctor Subs fixes structural issues (missing AS events, stuck-on-hold statuses, manual-renewal flag drift, line-item total drift). It does not handle card declines, SCA prompts, or retry strategy. For those, use your gateway’s built-in dunning or a dedicated plugin.
v2.1: Stripe fully supported across all rules that need a gateway signal (stuck on-hold, manual-renewal drift). The remaining rules are gateway-agnostic. PayPal, Authorize.net, Square, and WooPayments variants land in a future release.
Yes. The scanner uses a shared pre-built index so every rule is O(1) per sub (no N+1 queries). The DR_SUBS_SCAN_BATCH_SIZE constant lets you tune the batch size in wp-config.php for very large stores.
Yes. Implement DR_Subs_Rule_Interface and register on the dr_subs_register_rules action. See the six built-in rules under includes/rules/ for examples.
Required. Doctor Subs declares High-Performance Order Storage compatibility and requires WooCommerce 9.0 or higher.
WooCommerce ships a Subscriptions Health Check tool that flags two conditions: subs on manual renewal that have a valid saved payment token, and subs with a missing or overdue next-payment date. It surfaces them as a list and points you at the relevant order so you can act manually.
Doctor Subs overlaps on those two patterns (Manual-renewal drift, Ghost subscription) and adds four more the built-in tool doesn’t cover: mass on-hold cascade after a product edit, stuck on-hold despite a captured Stripe renewal, repeated payment failures within 30 days, and total drift between the stored total and line items.
It also wraps every detection in a preview-before-apply modal, one-click fixes, a per-entry revert journal, bulk-fix across N matches, state-guarded apply (aborts if the sub changed between detection and apply), and an optional email digest when something new breaks between scans.
Short version: WC’s tool is a flagger. Doctor Subs is a flagger plus a reversible repair surface. Running both is fine – they don’t conflict.
Reviews
Changelog
2.1.1
Docs only. New FAQ entry comparing Doctor Subs to WooCommerce’s built-in Subscriptions Health Check tool, with link to the official WooCommerce documentation. No code changes.
2.1.0
Major detection + UX expansion. Six rules now ship; design language tightened.
New rules (3):
- Manual-renewal drift (Stripe-only): detects active subs silently flipped to manual renewal despite a Stripe customer/source on file. Direct response to the four April 2026 subscriptions-core bug disclosures. Fix clears the flag in HPOS + postmeta, re-stamps next_payment if past-due, and schedules a fresh renewal.
- Mass on-hold cascade: detects 20 or more on-hold transitions for the same product within a 1-hour window. Backed by a new
dr_subs_status_transitionslog written by an observer on every subscription status change. Fix reactivates each cascade member; bulk-fix recovers the whole cascade in one click. - Total drift (flag-only): detects subs whose stored total no longer matches the sum of line items + tax + shipping + fees by more than $0.50, ignoring subs modified in the last 7 days. Surfaces the discrepancy and links to the sub for manual review.
Dashboard:
- Healthy counter relocated as an “X of Y healthy” stat above the action counters; can no longer be mistaken for a clickable filter.
- Search bar matches sub number, customer name, and billing email. Debounced, ESC clears.
- Rule chip filters above the table; bucket counter and rule chip are now mutually exclusive (clicking one clears the other).
- Reason column strips inline HTML so emphasis tags never render literally.
- Issue column header moved to screen-reader-only; the rule pill carries the label.
Bulk + revert:
- Bulk-fix button beside the active rule chip OR in “All rules” mode: groups visible rows by rule, posts one batch per rule, surfaces a styled confirm modal listing the per-rule counts and a renewal-payment warning. Total Drift opts out (manual-only).
- Revert confirm now opens a styled in-plugin modal instead of
window.confirm(). When the journal entry’s AS action has already executed, the modal escalates to a danger-styled button and the explicit “this will NOT refund” warning.
Settings:
- New “Detection rules” section listing all six rules with toggle, plain-English Detects/Fix descriptions, and bucket tag. Disabled rules skip detection on every scan.
- Plain-English summaries on dashboard rule chips and table pills via
DR_Subs_Rule_Catalog.
Fix history:
- Plain-English summary per row (“Rescheduled the missed renewal payment”, “Reactivated as part of a mass-hold cascade recovery”, etc.) instead of the raw
key: valueafter-state dump. - All canonical rule ids now render correct labels (legacy short ids fall back).
Schema + scanner:
- Schema bumped to 2.1.0; new
dr_subs_status_transitionstable withsub_id,from_status,to_status,product_id,variation_id,transitioned_at. Pruned daily on a 30-day TTL. - Scanner now walks
active,on-hold, andpending-cancelstatuses (wasactiveonly). Mass-hold + Stuck-on-hold rules now reach their target subs. - Manual_renewal_drift registered before Ghost_sub so it claims primary-rule on the same broken state with the right fix. Ghost_sub now skips manual-renewal subs entirely.
Design + accessibility:
- Display typeface swapped from Instrument Serif to Source Serif 4 (less editorial-romantic, calmer italic).
- Counter numerals dropped from 62px display serif to 32px Switzer 500: a 28-broken count no longer reads like a panic-amplifier.
- Dashboard hint copy de-imperative-d (“needs you now” -> “since last scan”).
- All em dashes / en dashes / minus signs replaced with plain hyphens across PHP, JS, CSS, and views.
- Modal focus on open lands on the dialog itself (tabindex=-1) so the sub-id link no longer reads as “selected”.
- New
.btn-dangertoken using the existing terracotta--brokenfor genuinely destructive actions.
Internal:
- New
DR_Subs_Rule_Catalogcentral source-of-truth for per-rule label, summary, detect, fix, bucket, and journal_summary copy. - New
dev/directory withseed-test-data.phpandwipe-test-data.php(excluded from the production zip via build script + CI workflow).
2.0.0-alpha.1
Major rewrite. Single breaking change moment: every PHP class renamed from WCST_* to DR_Subs_*; legacy class_alias shims ship for the three most-likely-extended public classes.
- Traffic-light dashboard with per-bucket drill-down
- Three deterministic detection rules: Ghost Sub, On-Hold with Paid Renewal (Stripe), Repeated Payment Failures
- Daily background scanner via Action Scheduler + WP-Cron watchdog
- One-click fixes with state-guarded apply and reversible Fix journal
- Fix preview modal with named diff and executed-payment warning
- Email digest alerts (off by default; configurable recipient)
- Settings page with retention controls and anonymous telemetry opt-in
- 20 language translations via Potomatic
- Self-hosted typography, no external asset fetches
- HPOS baseline (WC 9.0+)
1.2.4
- Fixed all security issues (sanitization, validation, escaping)
- Fixed Action Scheduler compatibility (scheduled_date_gmt column)
- Improved error handling and debugging
- Enhanced analyzer stability
- Added PHPCS configuration
1.2.3
- Initial release