# WordPress Plugin

Source: https://docs.ezoic.com/docs/subscriptions/wordpress-plugin/


The **Ezoic Subscriptions** plugin handles WordPress checkout pages, visitor login and server-side protection of posts and pages. Ezoic handles payments, purchases and the subscriber billing portal. The plugin loads the [onsite script](/docs/subscriptions/site-integration/) and registers a WordPress-account `AuthAdapter`. Do not add a second script tag or adapter on a site running it.

## Before You Start

Use WordPress 6.6 or later, PHP 7.4 or later, HTTPS, and an Ezoic account with this site added. Multisite is not supported. Complete [payment onboarding](/docs/subscriptions/payment-setup/) in your Ezoic account before selling access.

The plugin is separate from the Ezoic integration plugin and does not require it. Check your theme, other membership plugins and every cache layer before launch. In particular, review [protection limits](#protection-limits) and [caching](#caching).

## Setup and Go Live

1. In WordPress, go to **Plugins → Add New Plugin**, search for **Ezoic Subscriptions**, then click **Install Now** and **Activate**. Open **Ezoic Subscriptions → Dashboard**, click **Connect**, and approve the site connection in your Ezoic account. Connection failures and recovery controls appear under **Settings → Connection**.
2. Open **Settings → Visitor accounts**. If **Visitor account type** is not **WordPress accounts**, click **Switch to WordPress accounts**. This changes the login provider for the whole Ezoic domain, including any non-WordPress integrations on it.
3. Create or select an active product with a price under **Products**.
4. In **Settings → Checkout**, select a shared checkout page or use **Create checkout page**, then check **Default price**. Configure the login page in **Settings → Visitor accounts → Account pages**.
5. Add protection under **Paywall → Content rules** and configure **Paywall → Paywall message**.
6. Preview the pages and [make a test purchase](#test-mode). Configure cache exclusions before launch.
7. Return to **Dashboard → Go live**, resolve blocking checks and review warnings. Go live publishes the selected shared checkout and login drafts and enables visitor-facing behavior.
8. Purge all page caches and CDNs, then complete the [visitor checks](#verify-your-cache-and-visitor-journey) below.

**Connect does not create pages or change the login provider.** Before Go live, ordinary visitors see WordPress content as they would with the plugin inactive. Users who can edit posts see the plugin's frontend preview, identified by **Ezoic Subscriptions: preview — not live** in the admin bar. This is not a private launch: content can still be public and indexed before Go live.

Create checkout page and Create login page make drafts before launch; on a live site they create published pages. Dedicated checkout drafts have their own publication step. Review navigation menus that automatically list new pages.

**Turn off** ends the plugin's visitor-facing behavior but leaves published pages in place. Purge all caches afterward. **Disconnect** revokes the connection but does not turn off a live paywall; use Turn off when you intend to restore ordinary WordPress rendering.

## Products and Promo Codes

**Products** lists products, status, prices and checkout links. WordPress-created products can be edited here. Products managed in Ezoic or Open.Video are view-only; follow their management link to make changes there.

WordPress creates a product with one price, either a subscription or a whole-product one-time pass. Saved prices can be replaced or stopped, but there is no Add price action on an existing product. Existing subscriptions retain their billing terms. Per-article purchases are not supported by this plugin.

For an **Ad-free product**, logged-in buyers receive ad removal for Ezoic-served ads across the site. Other ad networks are unaffected. Logging out restores ads; when access ends, the browser's next ad-access check can take up to six hours while the visitor keeps browsing.

**Promo codes** supports creating codes and turning them on or off. Discount terms cannot be edited after creation; create a new code to change the offer. Active code details provide checkout links with `promo` prefilled. Checkout rechecks eligibility, so sharing a link does not guarantee that buyer receives a discount. An ineligible product, minimum amount or currency can leave the full price.

Turning a code off prevents new uses and can affect a discount promised for a trial's first payment. Review the confirmation. See [Promo Codes](/docs/subscriptions/promo-codes/) for discount rules.

## Checkout Pages and Links

The shared page selected in **Settings → Checkout** serves all eligible prices. Use **Products → Copy link** to get each price's address, typically `/checkout/?price=PRICE_KEY`. Without a price in the URL, checkout uses **Default price**. On an ordinary checkout page, a URL price takes precedence over a shortcode price:

```text
[ezoic_subscriptions_checkout price="PRICE_KEY"]
```

Use the checkout block's **Wide** or **Full width** alignment for a wider desktop layout. The plugin does not generate a pricing page; build your sales page in WordPress.

### Give a Price Its Own Page

Open a product's saved price and select **Use a custom checkout page**:

- **Create draft page** creates a page to edit and publish. The existing shared checkout link remains in use until the custom page is usable.
- **Choose existing page** lets you select a page you prepared in the WordPress editor. Add one Ezoic checkout block, choose **Use for one price**, and save. Return to Products, refresh the selection and confirm **Use page**.

A published, valid dedicated page sells its assigned price, ignoring a different `price` in the URL. It can work without a shared checkout page. If the dedicated page is unavailable, generated links use a usable shared page instead; without either, no checkout link is available. Removing an assignment preserves the page and its content, but its old checkout cannot continue selling that offer.

After changing an address, update copied links and cache exclusions. Do not assume the old address redirects.

### Return Buyers to the Article

Paywall actions can carry the original article to a pricing page, another public page or checkout. On a sales page, use the **Ezoic checkout link** block or its generated shortcode to forward that context; a plain checkout link does not forward it automatically. Checkout's **Continue** action can then return the visitor to the article.

Keep generated query strings intact. They can carry `price`, `promo`, `redirect_to`, `account=create` and `signup_return`. Changing or dropping them can select the wrong price or lose the account/article return destination.

## Protect Content

In **Paywall → Content rules**, select a post, page, tag or category and the products that unlock it. Visitors need access to a selected product.

- Every matching rule must select the same products. Different product selections block everyone, including subscribers; a post rule does not override a category rule's products.
- Category rules cover posts assigned to that category, not posts assigned only to a subcategory.
- **Roles that can read without buying** can exempt selected WordPress roles, except Subscriber. A visitor's role must be listed on every matching rule. This opens only the main article, not public feeds or REST output.
- Configured login and checkout pages are exempt from content rules.

**Paywall → Paywall message** controls heading, message, button and destination, and **Show excerpt above the paywall message**. Logged-out visitors and logged-in visitors without access can receive different messages or redirects. Rules can override those presentation choices: post, then tag, then category, then the Paywall message setting. Conflicting presentation choices at the same level use the default paywall message.

Redirects apply to the main article, not listings, feeds, REST or embeds. Page destinations must be published, public pages on this site.

### Protection Limits

The plugin withholds protected bodies on normal article, archive, search, feed, public REST and embed paths. It does **not** make excerpts private. WordPress still uses the Excerpt field or generates an automatic summary, which can contain the whole body of a short post. Write public-safe excerpts and metadata.

Comments remain subject to WordPress's own settings. Subscription rules do not hide discussion or restrict who can comment.

**Latest Posts in full-content mode is unsupported and can expose protected bodies.** Use excerpt mode, or a core Query Loop with Post Content for listings. Single-article templates built around an inherited Query Loop are not supported for subscriber unlocking.

Page builders that bypass WordPress's normal content rendering, plugins reading raw post fields, custom search indexes, SEO/AMP exports and translated rules need separate compatibility checks. Rules are not translated automatically for WPML or Polylang. Do not rely on searches matching words that occur only in protected bodies.

### Access Refresh and Outages

WordPress matches purchases to the logged-in account's email. It stores Ezoic's last access answer and refreshes it on protected article views: normally after five minutes for allowed visitors, or two minutes for denied visitors. After checkout, denied views recheck more frequently for a 30-minute window, subject to outage backoff.

Cancellation, expiry or revoked access takes effect after Ezoic reports it and the visitor's next successful refresh. There is no idle background refresh for every visitor.

When Ezoic cannot answer, a previously confirmed grant can remain usable until a new successful answer replaces it, even past its original expiry. Visitors without a usable stored grant remain behind the paywall. Ezoic switching off purchases stops new checkout but preserves last-confirmed visitor access. Disconnecting a live site can also preserve stored access for that connection; it does not make protected articles public.

## Visitor Accounts

Visitors sign in with WordPress accounts on your site. Ezoic's separate subscriber portal manages billing; signing in there alone does not sign the visitor into WordPress.

**After a guest purchase**, the plugin creates a Subscriber account for a new purchase email, sends a set-password email and logs the visitor in. If that email already has a WordPress account, the buyer must log in; the purchase does not replace the existing password or roles. If the visitor leaves checkout before account creation completes, a scheduled backstop can create the account later. It runs approximately every ten minutes through WP-Cron, so timing depends on the site's cron execution.

**Create account** opens the plugin form from login or checkout. It accepts email and password and signs the new visitor in immediately. It requires a connected, live site and does not depend on WordPress's **Anyone can register** setting. No confirmation email is sent for this signup.

Neither account-creation path verifies email ownership. Purchases are matched by email: an account registered for an address before its owner buys can receive that address's later purchases until the owner resets the password.

### Login, Passwords and Email

Under **Settings → Visitor accounts → Account pages**, choose the plugin's login form, an existing login form on the same site, or the standard WordPress login screen. An existing form URL must already work; entering its address does not create a form. Save with **Save visitor accounts**.

The Ezoic login block or `[ezoic_subscriptions_login]` places the plugin form. WordPress handles passwords and sessions. The standard `wp-login.php` remains available for administration. Check login, recovery, CAPTCHA and two-factor behavior with the security plugins installed on your site.

**Password requirements** applies to the plugin's Create account and Set password forms. Minimum length is 8–128 characters, default 12. **Password strength** offers **Any (length only)**, **Weak or stronger**, **Medium or stronger (recommended)** and **Strong**. Existing passwords keep working; native WordPress, staff and third-party forms retain their own rules.

**Account emails** sets **From name** and **From email** for purchase welcome and applicable visitor password-reset messages. Purchase welcome emails use Ezoic's English text; branded password resets apply to English-language visitors, with WordPress content used for other languages. Your WordPress mail service sends them and may override the sender. Test actual delivery. **Users → Awaiting set-password email** lists failed welcome emails and resend controls.

### Account Page

Add the Ezoic account block or `[ezoic_subscriptions_account]` to show logged-in visitors their subscriptions and payments for this site. Billing changes remain in the subscriber portal. The **Manage subscription** button opens it; use the account-link block or `[ezoic_subscriptions_account_link]` for that button alone.

These account elements appear for logged-in visitors. Exclude account pages from caching even if the theme places the block in a template or shared header.

The account block avoids standard Ezoic paragraph and video auto-insertion inside it; surrounding page ads remain. For manual exclusion in your ad plugin, use `.ezoic-subscriptions-account`; third-party inserters still need their own configuration.

## Test Mode

On the connected HTTPS site, sign in as an administrator and open **Ezoic Subscriptions → Products**. Click **Preview** beside a saved price, or **Preview in test mode** in the product editor. Save price changes first. Checkout opens in a new tab.

Before entering payment details, verify the visible **Test mode — no real charges** indicator. If it is absent, return to Products and start a fresh Preview. An invalid or expired preview link can leave a previous preview active or use live mode; do not infer test mode from the URL alone.

**Copy link** copies the ordinary checkout address. **Open checkout** uses the browser's current live or test mode; neither starts a new test session.

Test checkout uses your signed-in WordPress account, and earlier test purchases can still grant it access. Starting another preview does not delete them. Guest test purchases can create real local WordPress accounts and send real set-password emails.

Use [Stripe test cards and test-mode instructions](/docs/subscriptions/testing-sandbox/). Click **Exit** on the test-mode indicator when finished. Before Go live, ordinary visitors still see normal WordPress output, so complete the logged-out protection checks after launch too.

## Search Engines

In **Settings → Search engines**, **Let search engines index protected articles** enables verified crawler access. Choose Google and optionally Bing; configure **This site is behind Cloudflare** only when it matches your hosting setup. The plugin verifies source IPs against search-engine lists rather than trusting the user-agent name. Other proxies or load balancers that hide the source IP are unsupported.

The verified crawler can receive the full article with private/no-store headers. The plugin adds paywalled-content structured data; validate your actual theme's output with Google's [Rich Results Test](https://search.google.com/test/rich-results). **Allow Google’s testing tools** permits public testing tools to read protected articles; turn it off after checking. Search engines may quote protected text in results or AI answers.

Configure cache bypasses for Googlebot and bingbot so requests reach WordPress. This cache rule does not grant access: WordPress still verifies the crawler. Check the tab's **Status** after saving. Content indexed before Go live is not automatically removed from search indexes.

## Terms and Privacy

Use **Settings → Checkout → Terms & privacy** to enter your policy URLs and enable **Show policy links at checkout**. These are the same domain settings edited in your Ezoic account. WordPress's **Use this URL** suggestion uses the published Privacy Policy page selected under WordPress **Settings → Privacy** and fills the field without saving.

See [Terms and Privacy Links](/docs/subscriptions/subscriber-experience/#terms-and-privacy-links) for the checkout wording and limitations.

## Blocked IP Addresses

**Settings → Checkout → Blocked IP addresses** manages one list shared across live and test mode. Ezoic enforces it for the whole domain, including non-WordPress pages using Ezoic Subscriptions.

Each entry is one exact public IPv4 or IPv6 address, with an optional note up to 255 characters. The limit is 500 addresses. Ranges, expiration dates and Ezoic's reserved addresses are not supported. Add/remove actions need no separate Save; allow about 15 seconds for enforcement caches to update.

A blocked address cannot start checkout or a free trial, validate promo codes, or request an onsite login link. It can still read content it otherwise has access to. Blocking does not cover the subscriber portal or every follow-up step of an existing checkout. Use a firewall to block whole-site access.

Mobile carriers, offices and VPNs can share an address. Blocking it affects all visitors using it.

## Caching

A cached response can be served before WordPress runs. The plugin sends cache-control signals but does not configure or purge your cache plugin, host, proxy or CDN.

A healthy anonymous paywall response without a WordPress post password may be cached. Logged-in protected views, personalized responses and errors are private/no-store when headers can still be sent. Headers alone do not prove a cache respects them.

### Required Exclusions

Apply exclusions at **every** cache layer:

- Requests with `wordpress_logged_in_` or `wp-postpass_` cookies.
- All shared and dedicated checkout pages, login/password-reset pages, account pages, and Create account URLs, including `account=create`.
- Pricing and landing URLs carrying return context such as `redirect_to` or `signup_return`.
- `wp-login.php` and `wp-admin/`, including the connection callback at `wp-admin/admin-post.php`.
- The plugin REST namespace `/wp-json/ezoic-subscriptions/` and equivalent `?rest_route=/ezoic-subscriptions/...` URLs. The Dashboard's caching guidance lists this site's account endpoint addresses.

Preserve `Set-Cookie`, `Cache-Control: private` and `no-store`. Never share a response that sets a login cookie. Do not strip query parameters from checkout or account links.

For hosts deliberately caching ordinary anonymous **shared** checkout, the full query string must be in the cache key, including price, promo and return context. Credential views, context-bearing responses and dedicated checkout pages must still bypass. Excluding all checkout pages is simpler.

### Purge After Changes

Purge **all page caches and CDNs after Go live or Turn off**. A public article cached before Go live can otherwise remain public; a cached paywall can remain after Turn off.

After rule, tag/category, paywall-message or page-setting changes, purge affected articles, listings, archives and all URL variants, including tracking queries. Update exclusions after page-address changes. Dismissing a purge reminder does not clear anything, and clearing only the object cache does not clear HTML pages.

- **WP Super Cache:** use **Settings → WP Super Cache → Contents → Delete Cache** to clear its page cache. See [WP Super Cache](https://wordpress.org/plugins/wp-super-cache/).
- **BigScoots:** **Clear Cache for Specific Files (by URL)** purges the listed URLs; include affected articles, listings and query variants, and clear other layers separately. See [BigScoots cache documentation](https://help.bigscoots.com/en/articles/10490537-customizing-bigscoots-cache-with-actions-filters-helper-functions).

Historical checks of WP Super Cache 3.1.4 Simple mode and BigScoots Cache 5.0.2 Standard covered visitor isolation and manual purges in specific configurations. They do not certify other versions or settings. WP Super Cache 3.1.5 includes a later security fix; 3.1.4 is not an installation recommendation. BigScoots replaced no-store headers on bypassed responses; browser-storage implications and Boost remain unverified.

### Verify Your Cache and Visitor Journey

Use separate logged-in and logged-out browser sessions, with caching enabled:

1. Warm an unprotected article and confirm a cache hit as a control.
2. Open a protected article twice anonymously. For a cacheable inline paywall, confirm a cache hit after warming it. Check the paywall and public-safe excerpt; inspect page source for protected text.
3. Log in as a paid visitor and confirm the full article. Reopen that exact URL anonymously and as a visitor without access; both must remain denied.
4. Log out and press Back. Confirm protected content is no longer shown before reloading, then reload and check again.
5. Complete a test purchase, return to the article and open its plain URL in another tab.
6. Test signup, existing-account login, set-password email and recovery. Test different checkout prices and promo links.
7. If using post passwords, verify that the correct password alone does not bypass subscriptions.
8. Change a rule or taxonomy assignment, purge all affected URLs, and repeat the checks. Check archives, search, feeds and REST output as well.

If a cache shares personalized pages or protected bodies, exclude those URLs or disable that cache layer, purge old copies and repeat the checks before relying on it.

## Deactivation, Deletion and Data

Deactivation keeps the connection, settings and stored visitor access. Reactivation reuses the connection. Deleting the plugin attempts to revoke it and removes plugin settings, rules and stored visitor access; created pages and WordPress users remain.

WordPress stores connection credentials, settings and per-visitor access state. Ezoic receives visitor identity for access checks and checkout, and stores purchase and billing records. WordPress's privacy export/erasure tools include the plugin's stored visitor data; removing local data does not cancel a subscription or erase Ezoic's billing records.

For connection, plugin or account problems, contact [Ezoic support](https://support.ezoic.com/). Include the plugin version, affected URL, visible error and cache layers, without passwords or connection credentials. Direct subscriber billing changes to the [subscriber portal](https://subscriber.ezoic.com).

