# IAS Single Purchase Enforcer — CLI Reference - **Plugin slug:** `ias-single-purchase` - **Version:** 1.1.13 - **CLI namespace:** `wp ias single-purchase` - **Tier:** Free (no licence required) - **Summary:** Duplicate-purchase enforcement: inspect ownership, flush the cache, revoke ownership and purge a customer. This reference is generated from the WP-CLI command docblocks (do not edit by hand). Every command accepts `--format=`. Every mutating command supports `--dry-run` (resolve + audit, no writes) and `--yes` (skip the confirmation prompt); destructive commands additionally prompt unless `--yes` is given, and any bulk-delete command refuses to run without an explicit scope argument — a required `--filter` on the record-deletion commands, or another mandatory bound such as `--max-age-days` — rather than defaulting to delete-all. **Authentication / trust model:** these commands run under WP-CLI, whose trust boundary is shell access — there is no separate capability check. Irreversible commands (flagged below) are guarded by `--dry-run`, a confirmation prompt (or `--yes`), a required scope argument on any bulk delete (a `--filter`, or another mandatory bound such as `--max-age-days`), and a before-state entry in the suite-wide CLI audit log. ## Commands ### `wp ias single-purchase flush-cache` Invalidate the ownership cache for a customer or the whole site. For a single customer it clears the in-memory cache AND issues targeted object-cache deletes for every product the customer currently owns (mirroring the per-item deletes the order-status hooks use), so cached "owned" verdicts are cleared on a persistent object cache (Redis/Memcache) too — a plain clear_cache() cannot reach those from a cold CLI process, whose in-memory cache starts empty. A stale verdict for a product the customer no longer owns is not enumerable and expires on its 1-hour TTL; use --all for a full group flush, and the command warns when a persistent object cache is in use. With --all it walks every registered user in batches of 100 and then flushes the whole `ias_spe_ownership` object-cache group via ias_spe_flush_ownership_cache() as a backstop. **Synopsis:** `wp ias single-purchase flush-cache [] [--all] [--dry-run] [--yes] [--format=]` **Options:** - `[]` — Customer reference — numeric WP user ID, login, or email. Omit and pass --all to flush the entire site. - `[--all]` — Flush the ownership cache for every customer (and the whole cache group). - `[--dry-run]` — Report what would be flushed without clearing anything. - `[--yes]` — Skip the confirmation prompt (only used for --all). - `[--format=]` — Output format. **Examples:** ```bash wp ias single-purchase flush-cache 42 wp ias single-purchase flush-cache --all --yes wp ias single-purchase flush-cache customer@example.com --dry-run ``` **Related:** `wp ias single-purchase inspect`, `wp ias single-purchase owned`, `wp ias single-purchase owners`, `wp ias single-purchase purge-customer`, `wp ias single-purchase restore-ownership`, `wp ias single-purchase revoke-ownership` --- ### `wp ias single-purchase inspect` Report the plugin slug, version and CLI environment. **Synopsis:** `wp ias single-purchase inspect [--format=]` **Options:** - `[--format=]` — Output format. **Examples:** ```bash wp ias single-purchase inspect ``` **Related:** `wp ias single-purchase flush-cache`, `wp ias single-purchase owned`, `wp ias single-purchase owners`, `wp ias single-purchase purge-customer`, `wp ias single-purchase restore-ownership`, `wp ias single-purchase revoke-ownership` --- ### `wp ias single-purchase owned` List the products a customer already owns. Reflects the plugin's own ownership resolution: it honours the `check_owned` setting and the `ias_spe_ownership_order_statuses` filter, so an install with ownership checking disabled reports nothing. For a resolved account it matches the storefront identity clause — customer_id AND the account's login/billing email(s) — so prior guest purchases under the same email are listed, matching the re-purchase block they explain. **Synopsis:** `wp ias single-purchase owned [--format=]` **Options:** - `` — Customer reference — numeric WP user ID, login, or email. A bare email with no matching account is treated as a guest (only resolves when the guest_mode setting is 'email'). - `[--format=]` — Output format. **Examples:** ```bash wp ias single-purchase owned 42 wp ias single-purchase owned customer@example.com --format=json ``` **Related:** `wp ias single-purchase flush-cache`, `wp ias single-purchase inspect`, `wp ias single-purchase owners`, `wp ias single-purchase purge-customer`, `wp ias single-purchase restore-ownership`, `wp ias single-purchase revoke-ownership` --- ### `wp ias single-purchase owners` List the customers who own a product (inverse ownership query). Scans owned-status orders (per the `ias_spe_ownership_order_statuses` filter) for the product. On large stores use --max-orders to bound the scan; a capped scan emits a warning and may be incomplete. **Synopsis:** `wp ias single-purchase owners [--max-orders=] [--page=] [--per-page=] [--format=]` **Options:** - `` — Product reference — numeric ID or SKU. - `[--max-orders=]` — Safety cap on the number of orders scanned. - `[--page=]` — Page of owners (1-based). - `[--per-page=]` — Owners per page (capped at 1000). - `[--format=]` — Output format. **Examples:** ```bash wp ias single-purchase owners 42 wp ias single-purchase owners SKU-123 --format=json ``` **Related:** `wp ias single-purchase flush-cache`, `wp ias single-purchase inspect`, `wp ias single-purchase owned`, `wp ias single-purchase purge-customer`, `wp ias single-purchase restore-ownership`, `wp ias single-purchase revoke-ownership` --- ### `wp ias single-purchase purge-customer` > **⚠ Irreversible — `--dry-run` first.** 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. GDPR hard-purge: drop ALL ownership-related records and cache for a customer. The destructive counterpart to revoke-ownership. Removes the customer's entry from the `ias_spe_revoked_ownership` store and flushes their ownership cache. Because the WordPress account may already be deleted, the customer is resolved best-effort — a bare numeric ID or email is accepted even when no account exists — and the customer EMAIL is recorded in the audit context (not just the user ID) so the action stays traceable. The guest-email rate-limit transients are intentionally NOT purged: their keys fold in the client IP (`md5( identifier . client_ip )`) and so cannot be reconstructed from the email alone; they carry no PII and self-expire on a short TTL. The response reports this honestly under `rate_limit_transients` rather than issuing no-op deletes. Note: ownership is derived live from WooCommerce orders, which are NOT touched here (deleting order history is WooCommerce/GDPR-eraser territory). This clears the plugin's own per-customer state and caches only. **Synopsis:** `wp ias single-purchase purge-customer [--reason=] [--dry-run] [--yes] [--format=]` **Options:** - `` — Customer reference — numeric WP user ID or email. Accepted even when the underlying account has already been deleted. - `[--reason=]` — Optional free-text reason, recorded in the audit context. - `[--dry-run]` — Report what would be purged without changing anything. - `[--yes]` — Skip the confirmation prompt. - `[--format=]` — Output format. **Returns:** A JSON object: { dry_run, action, customer, customer_id, customer_email, reason, cleared, rate_limit_transients }. **Examples:** ```bash wp ias single-purchase purge-customer 42 --dry-run wp ias single-purchase purge-customer gone@example.com --reason="GDPR erasure" --yes ``` **Related:** `wp ias single-purchase flush-cache`, `wp ias single-purchase inspect`, `wp ias single-purchase owned`, `wp ias single-purchase owners`, `wp ias single-purchase restore-ownership`, `wp ias single-purchase revoke-ownership` --- ### `wp ias single-purchase restore-ownership` Restore a customer's ownership of a single product (inverse of revoke-ownership). Removes the (customer, product) pair from the `ias_spe_revoked_ownership` store that revoke-ownership wrote, so the plugin's live order-derived ownership is honoured again and the duplicate-purchase block re-arms for that pair. This is the surgical inverse of revoke-ownership — it touches only the named pair, unlike purge-customer which drops ALL of a customer's revocations. The customer's ownership cache is invalidated after the write — including a targeted object-cache delete of this (customer, product) verdict and the account's email-keyed guest verdict — so the restore takes effect on the next check even on sites with a persistent object cache. A legitimate re-purchase already clears the revocation automatically (the runtime prunes the pair when an order enters an owned status), so this command is primarily for an operator reversing a revoke without a new order — e.g. an erroneous chargeback revocation. **Synopsis:** `wp ias single-purchase restore-ownership [--reason=] [--dry-run] [--yes] [--format=]` **Options:** - `` — Customer reference — numeric WP user ID, login, or email. - `` — Product reference — numeric ID or SKU. - `[--reason=]` — Optional free-text reason, recorded in the audit context. - `[--dry-run]` — Report what would be restored without changing anything. - `[--yes]` — Skip the confirmation prompt. - `[--format=]` — Output format. **Returns:** A JSON object: { dry_run, action, customer, customer_id, customer_email, product_id, reason, restored }. **Examples:** ```bash wp ias single-purchase restore-ownership 42 100 --dry-run wp ias single-purchase restore-ownership customer@example.com SKU-123 --reason="reinstated" --yes ``` **Related:** `wp ias single-purchase flush-cache`, `wp ias single-purchase inspect`, `wp ias single-purchase owned`, `wp ias single-purchase owners`, `wp ias single-purchase purge-customer`, `wp ias single-purchase revoke-ownership` --- ### `wp ias single-purchase revoke-ownership` Revoke a customer's ownership of a single product. Ownership is computed live from WooCommerce orders, so there is no stored record to delete. This writes the (customer, product) pair into the `ias_spe_revoked_ownership` option; the plugin's `filter_revoked_ownership` filter (hooked on `ias_spe_customer_owns_product` at priority 99) then reads that store back on every request and forces the pair to read as NOT owned, without touching order history. The customer's ownership cache is invalidated after the write — including a targeted object-cache delete of this (customer, product) verdict and the account's email-keyed guest verdict — so the revocation takes effect on the next check even on sites with a persistent object cache. **Synopsis:** `wp ias single-purchase revoke-ownership [--reason=] [--dry-run] [--yes] [--format=]` **Options:** - `` — Customer reference — numeric WP user ID, login, or email. - `` — Product reference — numeric ID or SKU. - `[--reason=]` — Optional free-text reason, recorded in the audit context. - `[--dry-run]` — Report what would be revoked without changing anything. - `[--yes]` — Skip the confirmation prompt. - `[--format=]` — Output format. **Returns:** A JSON object: { dry_run, action, customer, customer_id, customer_email, product_id, reason, revoked }. **Examples:** ```bash wp ias single-purchase revoke-ownership 42 100 --dry-run wp ias single-purchase revoke-ownership customer@example.com SKU-123 --reason="chargeback" --yes ``` **Related:** `wp ias single-purchase flush-cache`, `wp ias single-purchase inspect`, `wp ias single-purchase owned`, `wp ias single-purchase owners`, `wp ias single-purchase purge-customer`, `wp ias single-purchase restore-ownership` ---