=== Leaky Paywall ===
Contributors: zeen101, layotte, pericson, endocreative
Requires at least: 5.6
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 5.1.2
Tags: paywall, metered paywall, subscription plugin, membership, content restriction
License: GPLv3
License URI: https://www.gnu.org/licenses/gpl-3.0.html

The subscription engine for news & niche publishers.

== Description ==

[Leaky Paywall](https://leakypaywall.com/) is the most flexible **paywall and subscription plugin for WordPress**. Launch a metered paywall, grow your email list with a registration wall, and sell paid subscriptions while keeping full control of your subscriber data inside WordPress.

https://www.youtube.com/watch?v=N_E64rMBJoY

Trusted by **800+ publishers worldwide**, including local newsrooms, niche magazines, B2B media companies, and independent content creators.

Leaky Paywall makes it easy to launch a subscription business without expensive enterprise software. Install the plugin, activate List Builder, and start building your audience in minutes.

= Launch a Paywall in Minutes =

With Leaky Paywall you can:

* Launch a **metered paywall**
* Add **paid subscriptions with Stripe**
* Capture reader emails with a **registration wall**
* Restrict content anywhere on your site
* Keep **full control of your subscriber data**

Everything runs **natively inside WordPress** with no external platform required.

= What's Included Free in Leaky Paywall =

Leaky Paywall includes powerful tools to start building your audience and monetizing your content right away.

= List Builder Registration Wall =

List Builder is a prebuilt **NYT-style registration wall** that turns anonymous readers into known subscribers.

Instead of popups, readers are prompted to register or log in seamlessly to continue reading.

* Activate in minutes with no design or development required
* Combined login and registration flow modeled after major news publishers
* Mobile-friendly and fully styled out of the box
* Grow your email list faster than traditional newsletter popups
* Export registered readers to your email platform or send via Zapier
* Sync subscribers with CRM integrations available on paid plans

= Multiple Subscription Levels =

Create as many subscription tiers as your business needs.

* Free, premium, annual, or VIP subscription tiers
* Unlimited levels with no upfront license cost
* Powered by Stripe with Apple Pay and Google Pay support
* Start free with **10% revenue share on paid subscriptions**
* Upgrade anytime to reduce or remove the revenue share

= Publisher Dashboard =

A dedicated dashboard inside WordPress gives you an instant view of your subscription business.

See:

* Revenue trends
* New subscriber registrations
* Paid subscription activity
* Top performing content

All directly inside your WordPress admin.

= Flexible Paywall and Content Control =

Leaky Paywall supports multiple paywall models so you can monetize your content your way.

* Metered paywalls
* Hard paywalls
* Dynamic and hybrid paywalls
* Restrict content by post, category, tag, taxonomy, or post type
* Restrict individual content blocks within articles
* Customizable paywall messaging
* Subscriber management tools
* Stripe payment processing (Verified Stripe Partner)
* REST API and developer hooks

= Upgrade to Leaky Paywall Pro =

As your subscription business grows, Leaky Paywall Pro unlocks powerful tools used by professional publishers.

= Revenue and Monetization =

* **Reduce or remove the 10% revenue share**
* Recurring subscriptions
* Free trials and promotional coupons
* Bulk, corporate, and group subscriptions
* IP-based subscriptions for organizations

= Data and Insights =

* **Subscriber Insights** helps identify readers most likely to subscribe
* Churn risk alerts
* Top converting content reports
* Subscriber behavior trends
* Incognito browsing blocking

= Integrations and Extensions =

Leaky Paywall integrates with the tools publishers already use.

* Salesforce
* HubSpot
* Mailchimp
* Zapier
* simplecirc
* Omeda
* WooCommerce

= Flowletter Newsletters =

Create and send newsletters directly inside WordPress with **Flowletter**.

Subscribers are automatically logged in when clicking from your newsletter, eliminating paywall friction and improving conversion.

Includes:

* Email automation
* Welcome sequences
* Free and paid newsletter tiers
* Subscriber segmentation

= Mobile Apps with UniPress =

Launch native **iOS and Android apps** connected to your WordPress site.

* WordPress content sync via API
* Paywall restrictions honored
* Push notifications
* Easy subscriber login

Leaky Paywall currently offers **50+ extensions** to expand your subscription business.

= Support =

Paid plans include **priority support**, onboarding assistance, and dedicated publisher success guidance.

[Upgrade to Leaky Paywall Pro](https://leakypaywall.com/upgrade-to-leaky-paywall-pro/)

= Perfect For =

Leaky Paywall is used by publishers of all sizes, including:

* Local news organizations launching digital subscriptions
* Niche magazines and membership publications
* B2B publishers selling premium research
* Independent writers monetizing their audience
* Content creators building subscription communities

Unlike hosted platforms like Substack or Ghost, **you retain full control of your subscriber data, content, and revenue inside WordPress.**

= Why Publishers Choose Leaky Paywall =

* **WordPress Native** — subscribers are stored as WordPress users
* **Free to Start** — launch without upfront costs
* **Flexible Monetization** — metered, hard, or hybrid paywalls
* **Full Developer Control** — extensive hooks, filters, and APIs
* **Trusted by 800+ publishers worldwide**

Leaky Paywall is backed by extensive documentation and an active development community.

= Get Started =

Leaky Paywall is free.

Install the plugin, activate List Builder, and start growing your audience today.

Ready to unlock advanced tools and keep more of your subscription revenue?

Upgrade to **Leaky Paywall Pro** for recurring subscriptions, deeper analytics, and powerful integrations.

* Learn more at [leakypaywall.com](https://leakypaywall.com/)
* Documentation: [docs.leakypaywall.com](https://docs.leakypaywall.com/)
* Publisher resources: [publisherrevenue.com](https://publisherrevenue.com/)
* Paywall Podcast: [leakypaywall.com/paywall-podcast](https://leakypaywall.com/paywall-podcast/)
* YouTube: [youtube.com/@leakypaywall](https://www.youtube.com/@leakypaywall)

== Installation ==

1. Upload the entire `leaky-paywall` folder to your `/wp-content/plugins/` folder.
2. Go to the `Plugins` page in WordPress and activate the plugin.

== Frequently Asked Questions ==

= How does Leaky Paywall work? =

The Leaky Paywall meter restricts by X number of free articles over a Y time period (days, weeks, months, years). There is a visibility setting on the post edit screen you can use to override the global meter setting, for example making an article always free or always require a subscription.

= What is List Builder? =

List Builder is a prebuilt registration wall and login system modeled after the New York Times. It prompts readers to register with their email to continue reading, helping grow your email list faster than traditional popup newsletter prompts. Registration and login happen in the same seamless flow.

= How does pricing work? =

Leaky Paywall 5.0 is free to install and use. If you add paid subscription levels, the free plan includes a 10% revenue share on new paid subscriptions. You only pay when you make money. Upgrade to a paid plan at any time to reduce or completely remove the revenue share.

= What payment gateways do you support? =

We support Stripe by default and are a Stripe Verified Partner. Apple Pay, Google Pay, and other methods are supported through Stripe. Paid plans unlock hundreds of additional international payment gateways via WooCommerce integration.

= What kind of subscriptions can I create? =

You can create multiple subscription tiers such as free, premium, annual, or VIP. The free plugin supports one-time payments. Recurring payments, trials, and coupons are available on paid plans.

= If I deactivate Leaky Paywall will I lose all my subscriber data? =

You can deactivate Leaky Paywall at any time without losing any subscriber data. All subscribers are stored as WordPress users in your database.

== Screenshots ==

1. Leaky Paywall general settings
2. Leaky Paywall content restriction settings
3. Leaky Paywall subscription level settings
4. Leaky Paywall payment method settings
5. Leaky Paywall visibility settings let you override the default restrictions on a per-content basis
6. Leaky Paywall subscriber table to manage current subscribers and manually add new subscribers
7. Leaky Paywall subscribe prompt after a reader has reached their article limit
8. Leaky Paywall subscribe cards
9. Leaky Paywall registration form for both free and paid levels
10. Leaky Paywall account page for subscribers to manage their account information

== Changelog ==

= 5.1.2 =
* Fix for race condition in registratin that could prevent fields from being saved correctly
* Fix REST API endpoint to keep expiration from being accidently updated
* Harden list builder scripts to load correctly even with performance add ons

= 5.1.1 =
* Add scaffolding for single Pro license key
* Add handling for multiple subscriptions during a sync
* Add dedup to registrations
* Add incomplete user cleanup functionality
* Add leaky_paywall_already_subscribed_at_level_content filter
* Allow search in subscriber table by first and last name
* Code cleanup for import tool
* Update handling of incomplete user during stripe webhook

= 5.1.0 =
* Stripe Payment Element now finalizes subscriptions via a webhook fallback when the browser redirect doesn't complete (e.g. Stripe Link, closed tab)
* Stripe Checkout webhook now dedupes by checkout session ID, preventing duplicate transactions from webhook retries
* Subscriptions that Stripe marks "canceled" while still inside their paid period now show as "pending_cancel" instead of immediately expiring
* customer.subscription.created webhook no longer activates users on incomplete subscriptions
* My Account page now shows "Cancels Soon" and "Expires on {date}" for pending_cancel subscribers
* REST PUT /subscribers now accepts an `expires` parameter and auto-calculates expiration when only `level_id` is supplied
* Stripe Connect admin notice no longer makes live API calls while in test mode
* leaky_paywall_new_subscriber and leaky_paywall_update_subscriber now record payment status changes in the status history log
* New filter `leaky_paywall_already_subscribed_at_level_content` lets extensions replace the message when a logged-in user tries to subscribe to a level they already have, e.g. to show a Resume Billing CTA for pending_cancel subscribers
* Stale `lp_incomplete_user` posts are now deleted daily after 30 days via Action Scheduler; configurable with the `leaky_paywall_incomplete_user_retention_days` filter (0 disables)
* Pro activation banner is now scoped to the Leaky Paywall Dashboard only (no longer appears on Settings/Tools/Subscribers) and is dismissible per user for 90 days
* Plugins page now exposes a License action link alongside Settings
* Fix: orphan `lp_incomplete_user` records no longer cause subscription renewals to be processed as new signups (duplicate "Initial Subscription Payment" transaction and admin new-subscriber email) — guarded both by a subscription_cycle gate in the Payment Intent finalize path and a 1-hour age check (filter: `leaky_paywall_incomplete_user_max_age_hours`) on the incomplete-user lookup
* Fix: subscriber list table search now matches first and last name user meta in addition to display_name, so subscribers whose display_name is their login or email are found by name search
* Fix: subscriber list table level and status filters now match exactly
* Fix: List Builder popup INP improved on mobile

= 5.0.9 =
* Email merge tags now support a fallback value for empty tokens, e.g. `%firstname|there%` renders "there" when no first name is on file
* Subscription Started and Subscription Renewed events now include previous_level and previous_level_id, enabling free-to-paid conversion tracking in Insights
* Non-recurring subscribers can now re-register on the same level to renew their subscription
* Fix paywall incorrectly appearing when a visitor revisits an article they've already viewed
* List Builder upgrade message now records nag location on conversion, so upgrades from logged-in subscribers appear in Top Content - Paid Conversions
* Status transition log now collapses rapid same-request transitions into a single entry, so a sync that briefly flips status no longer produces a chain of log rows
* New filter `leaky_paywall_target_subscriber_status` lets extensions veto or remap a status transition before it is written
* New filter `leaky_paywall_status_source_labels` lets extensions register custom human-readable labels for status transition sources

= 5.0.8 =
* Add list builder to top content conversions
* Fix save issue in email settings
* Update styling of dashboard
* Add self verification for deprecated paypal IPN

= 5.0.7 =
* Fix slow dashboard query

= 5.0.6 =
* Add checkout started event
* Update properties sent with events
* Add fix for in content nag displaying incorrectly
* Only update expires when the Stripe subscription status is active or trialing
* Add nonce check to settings
* Update cron handling of past due subscribers
* Adjust free count in dashboard to not include free to paid conversions
* Add hooks to dashboard widgets

= 5.0.5 =
* Add check for Stripe key before running script
* Add filter on the subscribe button for list builder
* Fix for free reg setting an incorrect expiration date
* Adjust list builder display for free sub level
* Add check for logged in user restrictions and previously viewed content
* Remove unnecessary nonce check for logged out visitors during restriction check
* Add undefined filter to level on subscriber table
* Fix upgrade messaging in admin
* Update default list builder settings

= 5.0.4 =
* Add new subscriber table filters and screen options
* Add filters for paywall allowed value and content viewed
* Add Stripe Tax integration
* Use terms and conditions setting on List Builder
* Fix logic for has access check in REST API
* Fix link colors in List Builder

= 5.0.3 =
* Fix duplicate display of the same user in subscriber table
* Fix restriction reset during login for list builder

= 5.0.2 =
* Fix possible double count of paywall views
* Adjust loading of list builder script
* Fix text domain compatibility warning
* Add list builder data to dashboard
* Fix for pressing enter on registration form
* Clear cancel at period end on level switch

= 5.0.1 =

= New =
* List Builder: Upgrade modal for logged-in free subscribers who hit the paywall, with independent enable/disable toggle and customizable heading, subheading, and button text
* List Builder: Auto-enables JavaScript cookie restrictions when List Builder is activated
* List Builder: Support for reCAPTCHA and Turnstile add-ons on the signup form

= Improved =
* Stripe billing address updates now apply to all attached payment methods, not just the default

= Fixed =
* Stripe PaymentMethod billing details not updating when customer's default payment method was unset

= 5.0 =
Major release introducing List Builder registration walls, a new Publisher Dashboard, onboarding improvements, deeper subscriber management tools, and expanded Stripe integration.

= New =
* List Builder added to core plugin for inline authentication and registration flows
* Multiple subscription levels restored to core functionality
* New onboarding wizard for faster setup
* New Publisher Dashboard with subscriber and revenue overview
* New Tools page with Import, Export, and Debug Log utilities
* Insights integration for tracking paywall impressions and nag statistics
* New email administration interface
* Subscription change flow added to the main registration form
* New subscriber statuses: expired, pending_cancel, and past_due
* Subscriber status transition logging and history on subscriber profiles
* Stripe webhook refund handling
* Transaction filtering (basic filters and date filters)
* Ability to block content using `0` in access settings
* Search engine bot bypass setting for SEO indexing
* Paywall schema markup (JSON-LD) for restricted content
* Terms and conditions settings
* REST API endpoints for Leaky Paywall subscribers

= Improved =
* Query performance improvements for Insights data
* Content restriction checks moved to REST API
* Updated WordPress dashboard widget with improved data display
* Migration script updated to use Action Scheduler
* Admin interface styling improvements (dashboard, transactions, subscribers, settings)
* CLS (Cumulative Layout Shift) styling improvements
* Stripe Connect setup flow with improved state verification
* General code cleanup and uninstall cleanup

= Fixed =
* Transaction deduplication checks
* Missing `isset()` check for connected_account_id
* Missing `isset()` check for amount_paid in Stripe object
* Float precision issue in price handling
* Translation string issues

= 4.22.6 =
* Add fix for low priority broken access control reported by patchstack

= 4.22.5 =
* Add handling for a free user during registration for a Stripe webhook if the page loading process fails
* Bump tested up to version

= 4.22.4 =
* Add fix for subscriber not created if registration page does not finish processing
* Add fix for duplicate transactions during a Stripe registration
* Add Stripe Connect params to Checkout API calls
* Add fix for authentication during Stripe Connect onboarding

= 4.22.3 =
* Add fix for possible duplicate transactions during registration when using Stripe

= 4.22.2 =
* Create a subscriber from a webhook if page does not load correctly after a registration

= 4.22.1 =
* Add level id throughout admin settings
* Allow subscriptions less than a dollar
* Fix formatting on subscriber admin page
* Adjust subscriber table columns
* Fix output of email exists error during registration
* Add check for subscription data to invoice payment succeeded event

= 4.22.0 =
* Add new subscriber admin screens
* Optimize Stripe code throughout plugin

= 4.21.8 =
* Add check for page link on login form if profile page is not set
* Add fix for direct link display in admin if register page is not set
* Update attributes in leaky_paywall_subscriber shortcode

= 4.21.7 =
* Add leaky_paywall_after_registration_submit_field action
* Add filter when retrieving a stripe plan
* Fix to parse shortcodes in leaky_paywall_not_subscriber output
* Fix index error

= 4.21.6 =
* Add setting for hiding registration form
* Update payment status during stripe sync
* Add additional logging

= 4.21.5 =
* Adjust customer lookup during Stripe webhook

= 4.21.4 =
* Add webhook check for incomplete_expired status from Stripe
* Update handling of Stripe errors when using a 100% off coupon

= 4.21.3 =
* Fix for CSRF vulnerability for deleting a level
* Process stripe payment element redirect url
* Add leaky_paywall_rest_meta filter
* Add webhook handling for the subscr_failed event from paypal
* Find user by email if subscriber id is missing
* Hide deleted levels from add new subscriber form

= 4.21.2 =
* Get stripe client secret from pending setup intent
* Add translation strings

= 4.21.1 =
* Add leaky_paywall_stripe_checkout_fields filter
* Update translation strings
* Fix ampersand display on register button

= 4.21.0 =
* Add check for paypal payment method when using multiple options on the register form

= 4.20.9 =
* Fix renewal email reminder functionality
* Fix price manipulation during registration
* Fix setting first and last name of logged-in users during registration if they do not exist yet
* Add after cancel action if the user cancels in the Stripe customer portal
* Add user parameter to leaky_paywall_user_has_access function
* Update stripe sync function to update expiration and plan

= 4.20.8 =
* Fix for free registration levels when using Stripe

= 4.20.7 =
* Add error checking to payment element
* Add check for succeeded payment intents
* Add level id when getting all levels

= 4.20.6 =
* Update Stripe to use the Payment element
* Update Stripe PHP library to latest version
* Add Stripe Billing Address element
* Update wording for tracking recurring payments
* Store nag location after stripe checkout registration
* Update translation strings
* Remove Apple Pay Stripe setting

= 4.20.5 =
* Add login form to register page
* Fix to not allow a user to register for a deleted level
* Update account shortcode actions
* Add links to stripe dashboard for stripe customers in subscriber table

= 4.20.4 =
* Fix login form display on profile shortcode

= 4.20.3 =
* Refactor profile shortcode to use actions instead of filters
* Move cancellation and payment update functionality to extensions

= 4.20.2 =
* Add date filter to content insights
* Add chart library for use in insights data
* Add link to renew license if invalid
* Fix typo in readme

= 4.20.1 =
* Add new interface for Insights
* Update plugin styling with new Leaky Paywall branding
* Fix PHP error for floats for Stripe

= 4.20.0 =
* Fix handling of Apple Pay to allow for coupons
* Add check for settings link display

= 4.19.9 =
* Add receipt email when using Stripe Elements
* Set float on Stripe price
* Fix test mode variable for PHP compatibility
* Update upgrade messaging

= 4.19.8 =
* Add general settings to Payment tab
* Do not process a plan for pay per post from stripe checkout
* Update default modal styles
* Add leaky_paywall_after_wp_user_profile_fields action

= 4.19.7 =
* Update tested up to to 6.2
* Add field data during stripe checkout
* Update wording on account page for trialing subscribers

= 4.19.6 =
* Update restriction rules for accessing a taxonomy when all taxonomies are restricted
* Update stripe checkout handling for alternative payment methods
* Check if a user has access when getting their current level id

= 4.19.5 =
* Add setting fields to create a new level if all levels have been deleted
* Update restriction logic for specific use cases
* Fix for PHP 8 error handling

= 4.19.4 =
* Fix for slashes in level settings
* Fix has access value in REST API data

= 4.19.3 =
* Display manual payment as an option on the registration form if multiple payment gateways are enabled
* Update calculation and display of currency symbol in Insights
* Display stripe customer portal on template shortcode
* Update help doc URLs
* Update logic for renewal reminders
* Fix deprecation notices for PHP 8
* Add Insights link to admin bar menu

= 4.19.2 =
* Add new Insights dashboard
* Add setting for restricting Stripe assets
* Fix broken links in admin
* Code cleanup

= 4.19.1 =
* Add setting for Stripe Customer Portal to My Account page
* Update currency and tax behavior on Stripe Checkout session
* Allow for script tracking in subscribe and upgrade nags

= 4.19.0 =
* Fix rounding off error for Apple Pay
* Add filters for stripe checkout session args
* Fix help link for webhooks
* Add function to format display price
* Update readme

== License ==

Leaky Paywall
Copyright (C) ZEEN101, LLC

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.