Building A Basic WP Membership / Paywall Feature Without A Plugin

By James LePage, CodeWP Founder
November 24, 2022

In this tutorial, we're going to take a look at how you can leverage several WordPress functions to build a surprisingly robust and extendable membership / gated content / paywall feature for your blog.

We'll be using core WordPress and no other plugins for this example, but you'll quickly see how simple and extendable this solution can become.

Let's say we run a popular WordPress website, and want to offer both public and members only content.

The Authentication Check

This is a simple, yet powerful snippet that makes use of several awesome WordPress functions.

The conditions that we're checking are:

  • Is a single WordPress post
  • The post has the category of "members"
  • The user has the custom role of "member"

These conditions are further broken down to:

  • Logged in users who don't have the role of "member": They are redirected to the /upgrade/ page
  • Logged out users : They are redirected to the login page with a custom message

If the conditions aren't met, the user is sent to their respective page, and cannot access the content.

add_action( 'template_redirect', 'members_only_redirect' ); function members_only_redirect() { if ( is_single() && in_category( 'members' ) && ! current_user_can( 'member' ) ) { if ( is_user_logged_in() ) { wp_redirect( '/upgrade/' ); exit; } else { wp_redirect( '/wp-login.php' ); exit; } } } Generation ID:cmpl-6FyGzqjE0k3oq4p12OL45Yk3LxBgc

The hook used is template_redirect which allows us to make this check well before any content is loaded.

Passing Along Contextual Information On Login

I'd also tack on a members only parameter to that redirect, wp_redirect( '/wp-login.php/?members-only-msg&postid=' . get_the_id(), 301 ), which we can then use to display a message on the login page, giving redirected users context as to why they were sent to this page.

Using and Displaying That Info On Login

function members_only_msg() { if (strpos($_SERVER['REQUEST_URI'], '?members-only-msg&postid=') !== false) { $post_id = $_GET['postid']; $post_title = get_the_title($post_id); echo '<p>You must log in to access content for ' . $post_title . '</p>'; } } add_action('login_form', 'members_only_msg');Generation ID:cmpl-6Fy4n9s3gRHC8X7QOw42rKfpY17eG

This is a basic example, but we can see that we're using $_GET['members-only-msg'] to check and see if the parameter is set, and if it is, echoing out a message.

We're also customizing it further by passing the ID of the post that the non authenticated user is trying to access, and use that to display the post title that they came from:

And just like that, it's pretty easy to build out a robust, yet simple "members only" system.

All of the code here is unedited CodeWP generations. With the right prompts, we can create some pretty complex paywalls and redirection rules, as shown below:

Prompt: Check if user has bought the a WooCommerce product at least 5 times, has an active subscription, and has had an account for over 3 years. If they meet these conditions, allow them to access WordPress posts with the "members-only" tag. If not, redirect them to the /gold-club/ page

Bonus: Excerpt Paywalls

What if you don't want to completely restrict somebody from accessing the post... not members only, but a paywall?

That's also pretty easy to do.

add_filter('the_content', 'members_only_content'); function members_only_content($content) { if (is_single() && in_category('members') && !current_user_can('member')) { $content = wp_trim_words($content, 100, '<a href="/upgrade/">Upgrade to read the rest of this post</a>'); } return $content; }Generation ID:cmpl-6FyUSjPnzutkgF0Y04Sf0rUdWEO1m

This snippet checks if the content is:

  • Is a single WordPress post
  • The post has the category of "members"
  • The user has the custom role of "member"

And if the user isn't a member, and the post is categorized for members, they'll get an excerpt of 100 words, and a link to the upgrade page that says "upgrade to read the rest of this post".

Bonus 2: Selling Access

You're probably thinking, "this is great, but how can I get the user to get the role of member?".

First, we'll register that role as it's not standard for WordPress:

add_role('member', 'Member', array( 'read' => true, // True allows that capability 'edit_posts' => true, 'delete_posts' => false, // Use false to explicitly deny )); Generation ID:cmpl-6FycX0B0BtXnZkMtm0nbw4b2kCOA5

Now, in the back end, you can add new users as members, or change existing user roles to this.

How about selling membership? Don't you need a plugin for that?

Not really. Instead, let's use WooCommerce and a $5 product called "Support Blog, Become a Member".

add_action( 'woocommerce_order_status_completed', 'wc_custom_user_role' ); function wc_custom_user_role( $order_id ) { $order = wc_get_order( $order_id ); $items = $order->get_items(); foreach ( $items as $item ) { $product_id = $item->get_product_id(); if ( $product_id == 5 ) { $user_id = $order->get_user_id(); $user = new WP_User( $user_id ); $user->set_role( 'member' ); } } } Generation ID:cmpl-6FyhCf9MbHww4u7g2VlrzkOwoTvzS

This code checks to see if they buy that product (assuming the ID is 5). If they do, the user's role is updated to 'member', and they have access to all of the gated content. Keep in mind, this is a bit simple for paid membership system, but it gets the point across!


Membership and paywall plugins for WordPress are great, but sometimes you just don't need them. This article shows a couple of concepts you can use to implement a simple membership system, using CodeWP generated code.

Snippets In This Tutorial Were Generated With CodeWP
PHP, JS or jQuery
AI models trained for WordPress & popular plugins
Unlimited generations
100% free trial
Start For Free