Every command accepts --format=<json|table|csv|yaml>. Commands marked Write accept --dry-run (resolve, audit, write nothing) and --yes (skip the prompt). Commands marked Irreversible additionally prompt unless --yes is passed, and any bulk delete refuses to run without an explicit scope argument rather than defaulting to delete-all.
Runs under the renewal lock. Uses the same path the admin/REST cancel uses — Subscription::update_status() (and update_dates() for the end-of-period case) — so downstream refund/licence/email side effects driven by the status hooks all fire. Without --immediate the subscription becomes pending-cancel with its end date set to the next payment date, which schedules the end-of-period cancellation.
Options
Argument
Required
Type
Description
<id>
yes
positional
Subscription ID.
[--immediate]
no
flag
Cancel now instead of at the end of the current paid period.
[--reason=<text>]
no
flag (value)
Note recorded against the cancellation.
[--dry-run]
no
flag
Report what would happen without changing the status.
This command permanently destroys data or applies a terminal state that cannot be undone from the CLI. Preview the exact effect with --dry-run, then re-run with --yes once you are certain.
Permanently delete a subscription and all its rows (NON-RECOVERABLE).
Unlike cancel — which keeps the subscription record and only changes its status — this HARD-deletes the subscription and its items, meta, order links and (unless --keep-audit) its event log from the database. Runs under the renewal lock and re-fetches inside it. There is no undo.
Options
Argument
Required
Type
Description
<id>
yes
positional
Subscription ID.
[--keep-audit]
no
flag
Preserve the subscription's event-log rows (ias_subscription_log).
[--dry-run]
no
flag
Report what would be deleted without removing anything.
[--yes]
no
flag
Skip the confirmation prompt.
[--format=<format>]
no
flag (value)
Output format.
Returns
The deleted subscription ID and the list of tables cleared.
This command permanently destroys data or applies a terminal state that cannot be undone from the CLI. Preview the exact effect with --dry-run, then re-run with --yes once you are certain.
Permanently delete every subscription matching a JSON filter (NON-RECOVERABLE).
A guarded bulk variant of delete. The --filter JSON is REQUIRED; there is deliberately no --all switch. Each matched subscription is hard-deleted under its own renewal lock. Capped at 1000 matches per run.
Options
Argument
Required
Type
Description
--filter=<json>
yes
flag (value)
Required JSON object selecting which subscriptions to delete. Supported keys: status (string), customer_id (int), product_id (int), import_batch (string — the wcsimp-… batch minted by import-wcs, which makes a bad import reversible with the existing destructive machinery rather than a second destructive command). Keys combine as AND.
[--keep-audit]
no
flag
Preserve each subscription's event-log rows (ias_subscription_log).
[--dry-run]
no
flag
Report the matched set and counts without removing anything.
A migration source, not a report. Each record carries the billing schedule, the parent order and every related order, the line items, the meta and the payment-method reference — enough to reconstruct the subscription elsewhere.
NOT licence-gated, deliberately. A lapsed licence must never strand a merchant's own subscriber records: the rows would still sit in ias_subscriptions with no supported way out. Being able to leave is a reason to buy. (Same call as wp ias serial-keys export and the License Activator's CSV export.)
Billing survives the move. Renewals are taken by setting the payment method on a renewal order and letting the standard WooCommerce gateway charge it, so the mandate and token live in WooCommerce's token store and the gateway account — not in this plugin. payment_method and payment_token_id are references into those, so exporting them carries the ability to keep billing without exporting anything that can charge a card on its own.
Options
Argument
Required
Type
Description
--file=<path>
yes
flag (value)
Destination file path.
[--format=<format>]
no
flag (value)
Export FILE format. JSON is the default because a subscription has nested line items, related orders and meta; CSV flattens those to JSON-encoded cells and is for spreadsheets rather than for migration.
[--status=<status>]
no
flag (value)
Restrict to these statuses (comma-separated, e.g. active,on-hold).
[--customer=<customer>]
no
flag (value)
Restrict to one customer (numeric WP user ID or email).
[--gateway=<gateway>]
no
flag (value)
Restrict to one payment gateway (e.g. stripe, ppcp-gateway).
[--product=<product>]
no
flag (value)
Restrict to one product ID.
[--dry-run]
no
flag
Report how many subscriptions would be exported without writing the file.
List the sign-up fee(s) attached to a subscription.
wp ias subscriptions fees list <id> [--format=<format>]
Per-subscription fees are not stored as line items; the sign-up fee is read from the subscription's product. Switch/proration fees are computed at renewal time and are not listed here. Each row carries a waived flag read from the _ias_sub_waived_fees meta (set by fees waive) — an observational reporting marker only; it does not affect what is charged.
Sign-up fees are one-time charges assessed at the INITIAL checkout, before a subscription exists, so there is no later assessment for a waiver to suppress (the plugin has no resubscribe flow, and plan switches charge a freshly computed proration, not a sign-up fee). This command therefore records an observational marker: it appends the fee id to the subscription's _ias_sub_waived_fees array meta and logs a fee_waived event. The marker is surfaced by fees list (the row's waived flag) for reporting and reconciliation; it does NOT itself alter, refund, or suppress any charge — no charge-assessment path consults this meta. Because the write touches no money path, it is intentionally not wrapped in the renewal lock (it is a per-key meta upsert that only ever races a concurrent fees waive on the same id).
Options
Argument
Required
Type
Description
<id>
yes
positional
Subscription ID.
<fee_id>
yes
positional
Fee identifier to waive (e.g. sign_up).
[--reason=<text>]
no
flag (value)
Note recorded against the waiver.
[--dry-run]
no
flag
Report what would happen without recording the waiver.
[--yes]
no
flag
Skip the confirmation prompt.
[--format=<format>]
no
flag (value)
Output format.
Returns
The subscription ID, the waived fee id and the resulting waived-fee marker list (a reporting record; it does not change any charge).
WCS hook compatibility keeps other plugins working but moves no data: a store with 500 live WCS subscriptions cannot switch on compatibility alone. This turns shop_subscription records into ias_subscriptions rows while preserving the one thing that makes a migration real rather than cosmetic — the ability to keep billing. The mandate and the card live in the gateway account and in WooCommerce's own token store, not in either plugin, so moving rows on the same store preserves them; this command translates the gateway REFERENCES onto the keys the IAS renewal engine reads.
Reads the source with raw SQL from either storage backend, never the wcs_*() API: with WCS deactivated those functions do not exist, and this plugin's own compatibility shims would answer with IAS data instead. It therefore works with WCS active, deactivated, or deleted with its data left behind. The WCS source is never modified by any phase of this command, which is what makes the rollback trustworthy.
Options
Argument
Required
Type
Description
[--execute]
no
flag
Actually write the subscriptions. Without this the command only reports.
[--dry-run]
no
flag
Explicit alias for the default behaviour (report only).
[--reconcile]
no
flag
Re-read the source behind every already-imported subscription and report drift instead of importing. Read-only; runnable any time after an import.
[--batch=<id>]
no
flag (value)
With --reconcile, restrict to one import batch.
[--status=<list>]
no
flag (value)
Restrict to these statuses (comma-separated, e.g. active,on-hold).
[--customer=<customer>]
no
flag (value)
Restrict to one customer (numeric WP user ID or email).
[--limit=<n>]
no
flag (value)
Maximum number of source subscriptions to consider.
[--offset=<n>]
no
flag (value)
Skip this many source subscriptions.
[--source-backend=<backend>]
no
flag (value)
Which storage backend to read the source from.
[--overdue=<policy>]
no
flag (value)
What to do with active subscriptions whose next payment is already in the past. bill imports them as-is and the renewal sweep charges them once (the WCS-faithful behaviour); hold imports them as on-hold so nothing bills until reviewed.
[--allow-wcs-active]
no
flag
Proceed even though the real WooCommerce Subscriptions plugin is active.
[--report=<path>]
no
flag (value)
Write the full per-record detail to a JSON file.
[--yes]
no
flag
Skip the confirmation prompt on --execute.
Returns
A JSON summary: what would be created, what was skipped and why, every warning class with the source IDs it applies to, the unmappable records with reasons, and an expected_next_charges preview so the money can be reviewed before anything is written.
Resolves licenses by the subscription's product + customer via the License Activator integration (ias_license_get_product_licenses). When the License Activator is not active this reports no link.
Runs under the renewal lock and re-fetches inside it. Delegates the state change to Subscription::update_status('on-hold'), which fires the standard WCS-compatible and IAS status hooks.
Options
Argument
Required
Type
Description
<id>
yes
positional
Subscription ID.
[--reason=<text>]
no
flag (value)
Note recorded against the status change.
[--dry-run]
no
flag
Report what would happen without changing the status.
This is the legitimate revival path the M-A-R3 audit preserved: moving a terminal subscription back to active. Runs under the renewal lock. Allowed only from cancelled or expired. As a guard against accidentally reviving long-dead subscriptions, revival is blocked when the terminal (cancelled/end) date is older than the window (default 90 days; filter ias_sub_cli_reactivate_max_age_days) unless --force is given.
Options
Argument
Required
Type
Description
<id>
yes
positional
Subscription ID.
[--force]
no
flag
Revive even if the subscription has been terminal longer than the window.
[--dry-run]
no
flag
Report what would happen without changing the status.
Delegates to Renewal_Handler::process_renewal(), which acquires the renewal lock, re-checks the subscription is still active (the M-A-R3 guard), creates the renewal order and charges the gateway. Only active subscriptions renew.
Options
Argument
Required
Type
Description
<id>
yes
positional
Subscription ID.
[--dry-run]
no
flag
Report what would happen without creating an order or charging.
Runs under the renewal lock. Delegates to Subscription::update_status('active'); the Failed_Payment_Handler clears any retry/dunning state on the transition to active, so the subscription re-enters the normal renewal sweep.
Options
Argument
Required
Type
Description
<id>
yes
positional
Subscription ID.
[--dry-run]
no
flag
Report what would happen without changing the status.
Queues a plan switch by storing the _pending_switch_variation_id meta. The new plan takes effect at the NEXT renewal: Renewal_Handler::process_renewal() applies the pending switch BEFORE building the renewal order, so the renewal charges the NEW price and then advances the schedule by the NEW period — it is never charged at a stale old price. With --immediate the switch is applied to the subscription right now via the same apply path. This CLI command does NOT take an immediate card payment; the proration figure is REPORTED for reference only (a real upgrade charge happens through the customer/admin switch flow, not here).
Options
Argument
Required
Type
Description
<id>
yes
positional
Subscription ID.
<new_variation_id>
yes
positional
The variation ID of the plan to switch to (must belong to the same parent product).
[--prorate=<bool>]
no
flag (value)
Whether to compute and report the would-be proration charge for reference.
[--immediate]
no
flag
Apply the switch to the subscription now instead of at the next renewal.
[--dry-run]
no
flag
Report what would happen without storing the pending switch or applying it.
[--yes]
no
flag
Skip the confirmation prompt.
[--format=<format>]
no
flag (value)
Output format.
Returns
The resulting status, variation and recurring total (after, when --immediate).
End a subscription's trial immediately so billing can proceed.
wp ias subscriptions trial end <id> [--dry-run] [--yes] [--format=<format>]
Clears the trial_end date. Runs under the renewal lock, re-fetches inside it, and persists via save(). This ends the trial window; the next scheduled renewal charges as normal. It does NOT itself take an immediate payment.
Options
Argument
Required
Type
Description
<id>
yes
positional
Subscription ID.
[--dry-run]
no
flag
Report what would happen without clearing the trial date.
[--yes]
no
flag
Skip the confirmation prompt.
[--format=<format>]
no
flag (value)
Output format.
Returns
The subscription ID and the trial_end date that was cleared.
Examples
wp ias subscriptions trial end 17 --dry-run
wp ias subscriptions trial end 17 --yes
Pushes the trial_end date forward by --days. Runs under the renewal lock, re-fetches inside it, updates the date and persists via save(). Errors if the subscription has no trial. This does not itself take a payment — the first charge happens at the (now later) end of the trial.
Options
Argument
Required
Type
Description
<id>
yes
positional
Subscription ID.
--days=<n>
yes
flag (value)
Number of days to extend the trial by (positive integer).
[--dry-run]
no
flag
Report what would happen without changing the trial date.
[--yes]
no
flag
Skip the confirmation prompt.
[--format=<format>]
no
flag (value)
Output format.
Returns
The subscription ID with the old and new trial_end dates.