• Skip to main content
  • Skip to primary sidebar
  • Skip to footer

nSiteful Web Builders

Building a Better Web - One Site at a Time.

  • Home
  • About
    • Testimonials
    • Resources
    • Partner With Me
    • Frequently Asked Questions
  • Web Sites
  • Online Marketing
  • WordPress Support
    • Customized WordPress Training
    • 60-for-60 Sessions
  • Web Applications
  • Blog
    • At-A-Glance
    • Blog Articles Grouped by Category
    • Case Studies
    • General
    • Portfolio
    • Reviews
    • Snippets
    • Techniques
    • Projects
  • Contact
    • Purchase Retainer Consulting Hours
    • About Retainer Consulting Hours
    • Book a Meeting with Jeff
    • Tell Me About Your Web Project
    • nSiteful Newsletter Archives
    • nSiteful Rewards
Custom MemberPress Pricing Pages

By Jeff - 12/19/2025
Cats: Techniques · Tags: MemberPress, Membership Sites

techniques

Custom MemberPress Pricing Pages

On This Page...

Toggle
  • Groups in MemberPress
  • Prerequisites
  • The Scenario: A Dance School/Studio
    • Creating a Group for this scenario
      • First let’s look at the upgrade/downgrade path issue.
      • Now let’s look at the mutuallly exclusive alternatives issue.
  • An alternate approach to a membership pricing page
    • The Code for the Custom MemberPress Pricing Page
      • Code for the array of information for the cards
      • Code to render the membership plan cards
      • Add the shortcode
      • Place the shortcode in the pricing page
      • The CSS
  • Comments and Questions Most Welcome

Last updated January 13th, 2026 at 07:26 pm

Groups in MemberPress

MemberPress has a built-in Groups feature — a tool that affects both front-end presentation and back-end functionality.

As the official MemberPress documentation states, MemberPress Groups allow you to quickly and painlessly set up a nice features comparison page for users to get a quick snapshot of the various Memberships you offer.

Beyond presentation — and this is important — Groups also have an effect on the back-end functioning of the membership system. Namely, they:

  • define upgrade and downgrade paths between membership plans
  • establish all plans within the group as mutually exclusive alternatives, not as independent products.

Accordingly, the Groups feature has some important limitations and disadvantages which, under some some circumstances, militate against using the feature at all and/or for displaying front-end pricing pages.

In this article I’ll explain those limitations and disadvantages using a real-world scenario, and I’ll give you step-by-step instructions for creating your own membership pricing page that circumvents them.

Prerequisites

To understand and be able to implement this solution, it’s best if you have

  • at least a basic understanding of how MemberPress Groups work
  • FTP access or access to a plugin such as Code Snippets
  • some experience writing PHP code, as it’s inevitable that your requirement will vary from mine, and you’ll need to modify the code
  • some experience writing CSS markup, for the same reasons as above
  • a relationship with a web developer, if you don’t have some of the above

The Scenario: A Dance School/Studio

The website is for a dance studio that offers, among other things, access to online video courses and a library of show recordings of performances given by students and faculty over the past two decades. MemberPress is used for managing access to this content.

  1. There are three membership “families”: All Video Courses; All Show Recordings; and a Courses & Shows Bundle.
  2. Each membership family has two plans: Monthly and Annual.
  3. The only thing that distinguishes the plans within a membership family is the term and cost. In other words, the monthly and annual plans offer identical perks.

Creating a Group for this scenario

Our first inclination might be to put all six membership plans in a group. If we did, the resulting group pricing page would look like this:

Pricing page generated by the Group functionality
Pricing page generated by the Group functionality

But there problems here, related to the upgrade/downgrade path issue and the mutuallly exclusive alternatives issue.

First let’s look at the upgrade/downgrade path issue.

The presence of membership plans in a group — and their order of appearance (in this case, left-to-right, top-to-bottom) — dictate how users can move through the membership plans.

It makes sense that a member could upgrade from Plan A to Plans B, E, or F.

It also makes sense that a member could upgrade from Plan C to Plans D, E, or F.

But moving from Plans A or B to Plans C or D doesn’t make sense and thus isn’t a valid upgrade.

Think about it…

The audience for the Video Courses memberships (A and B) would likely consist of current and prospective students of the dance studio.

The audience for the All Show Recordings memberships (C and D) would likely consist of the performers in those shows (most of whom will be either teachers or students of the studio), but also friends and family members of those performers.

While there’s overlap between those audiences, they are nonetheless distinct.

Therefore, putting all membership plans into one group doesn’t work for upgrades and downgrades.

Now let’s look at the mutuallly exclusive alternatives issue.

People need the freedom to sign up for one of the Video Courses plans and one of the Show Recordings plans. However, if these plans are part of the same MemberPress group, that’s not permissable. Plans within a group are not alternatives. A user cannot have subscriptions in more than one plan within a group.

If you’re thinking that the Courses & Shows Bundle plans take care of that situation, you’re close but no cigar. What about the user who wants to subscribe to the monthly Video Courses plan and the annual Show Recordings plan?

An alternate approach to a membership pricing page

So, we can’t use the native pricing page generated by the Group.

But we can code one up.

First, here’s a screenshot of my mockup of the custom MemberPress pricing page I want for our scenario.

Custom MemberPress Pricing Page Screen Shot
Custom MemberPress Pricing Page Screen Shot

Not only are we freed from the limitations imposed by the MemberPress Groups logic, but we’re able to simplify the pricing page by using one card for both plans for each membership.

The Code for the Custom MemberPress Pricing Page

Wherever I recommend adding code to your site, there are several ways you can do so, including:
  • add it to a script file in the /wp-content/mu-plugins/ directory (recommended)
  • add it as a standalone plugin to your /wp-content/plugins/ directory
  • add it to the functions.php file in your site's child theme directory
  • use a code snippets plugin such as Code Snippets
  • add it to the functions.php file in your theme directory (discouraged)

I created a PHP file in the mu-plugins directory. It consists of two functions.

Code for the array of information for the cards

The first function assembles (and returns) a multi-dimensional array all of the information for each of the three membership families.

function sd_odv_plans() {
	$plans[] = array(
		'name' => 'All Video Courses',
		'price_monthly' => '20',
		'price_yearly' => '199',
		'membership_id_monthly' => '33102',
		'membership_id_annual' => '33103',
		'annual_savings' => 'Annual Plan Saves 17%!',
		'benefits' => array(
			'All Video Courses',
			'Upgradable',
			'Auto-Renews',
			'Cancel any time before your subscription renews',
		),
	);
	$plans[] = array(
		'name' => 'All Show Recordings',
		'price_monthly' => '10',
		'price_yearly' => '99',
		'membership_id_monthly' => '33105',
		'membership_id_annual' => '33104',
		'annual_savings' => 'Annual Plan Saves 18%!',
		'benefits' => array(
			'All Show Recordings',
			'Upgradable',
			'Auto-Renews',
			'Cancel any time before your subscription renews',
		),
	);
	$plans[] = array(
		'name' => 'Courses & Shows Bundle',
		'price_monthly' => '25',
		'price_yearly' => '249',
		'membership_id_monthly' => '33112',
		'membership_id_annual' => '33113',
		'annual_savings' => 'Annual Plan Saves 17%!',
		'highlight' => 'highlighted',
		'benefits' => array(
			'All Shows and All Courses',
			'Best Value',
			'Auto-Renews',
			'Cancel any time before your subscription renews',
		),
	);
	return $plans;
}

Code to render the membership plan cards

The second function calls the first function and then renders the membership plan cards.

function sd_render_odv_plans() {
	$plans = sd_odv_plans(); // Call the function that creates the array
	ob_start();
	foreach ( $plans as $plan ) {
		$benefits = $plan['benefits'];
		$highlight_class = $plan['highlight'] ?? 'normal';
		$membership_id_monthly = $plan['membership_id_monthly'];
		$membership_id_annual = $plan['membership_id_annual'];
		$registration_page_monthly 	= '[mepr_membership_link id="' . $membership_id_monthly . '"]';
		$registration_page_annual 	= '[mepr_membership_link id="' . $membership_id_annual  . '"]';
		?>
		<div class="card odv-plan-card <?php echo $highlight_class;?>">
			<div class="odv-plan-name">
				<?php echo $plan['name'];?>
			</div>
			<div class="odv-benefits">
				<?php foreach ( $benefits as $benefit ) : ?>
					<div class="odv-benefit">
						<?php echo $benefit;?>
					</div>
				<?php endforeach; ?>
			</div>
			<div class="annual-savings">
				<?php echo $plan['annual_savings'];?>
			</div>
			<div class="odv-registration-link odv-registration-monthly">
				<div><?php echo do_shortcode($registration_page_monthly);?></div>
				<div class="price">$<?php echo $plan['price_monthly'];?>/mo</div>
			</div>			
			<div class="odv-registration-link odv-registration-annual">
				<div><?php echo do_shortcode($registration_page_annual);?></div>
				<div class="price">$<?php echo $plan['price_yearly'];?>/yr</div>
			</div>			

		</div>
			<?php }
	return ob_get_clean();
}

Add the shortcode

Add this one-line call to the add_shortcode function:

add_shortcode('render_odv_plans', 'sd_render_odv_plans');

Place the shortcode in the pricing page

Then, in the page that uses this shortcode, add this after any introductory content you wish to display:

<div class="odv-plans">[render_odv_plans]</div>

The CSS

.odv-plans {
	display: flex;
	flex-direction: row;
	column-gap: 1em;
	justify-content: space-evenly;
	flex-wrap: wrap;
	row-gap: 1.6rem;
}
.odv-plan-card {
	text-align: center;
	box-shadow: 0 0 2rem var(--color-dark-brown);
	padding: 1rem 2rem;
	border-radius: 1.2rem;
	width: clamp(300px, 32%, 800px);
}
.odv-plan-name {
	font-size: 3.2rem;
	line-height: 1em;
	margin-bottom: 2rem;
}
.odv-benefits {
	border-block: 1px solid #999;
	margin-block: 1.4rem;
	padding-block: 1rem;
}
.odv-registration-link {
	margin-block: 2rem;
}
.odv-registration-link .price {
	font-size: 3rem;
	line-height: 125%;
	font-weight: 900;
	color: #999;
}
.odv-benefit {
	line-height: 135%;
	margin-block: 0.5rem;
}
.annual-savings {
	font-style: italic;
	font-size: 2rem;
	font-weight: 700;
	text-wrap: balance;
	line-height: 115%;
	text-shadow: 0 0 5px yellow;
}

Comments and Questions Most Welcome

Let me know in the comments section below what you think. Does this solution make sense? Do you have other ideas? Have you encountered similar issues with the MemberPress Groups feature? Do you need more details?

Like what you see? Share with others and join my mailing list. No long-term commitment, unsubscribe any time.

Related Posts

  1. Avoid Direct Styling; Use CSS Instead
  2. Create Accordions & Toggles in WordPress with HTML and CSS Only
  3. Custom Front-End Member Listing for MemberPress Website
  4. Give Gutenberg a Chance
  5. How To Use MemberPress to Protect Posts that Contain Custom Fields

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

mailchimp signup

Subscribe to get notified when new articles are published. Unsubscribe any time. No spam. I promise. Check out my newsletter archives.

social

Twitter Facebook LinkedIn

Recent Articles

  • Post-Specific CSS for WordPress October 5, 2026
  • You built an online course, but they haven’t come. September 16, 2026
  • Custom MemberPress Pricing Pages December 19, 2025
  • CSS Data Attribute Override December 11, 2025
  • MemberPress Rules Using Custom Taxonomies and Custom Roles December 10, 2025

Filter By Category/Tag

Categories

  • Case Studies (8)
  • For Staff (1)
  • General (73)
  • Portfolio (7)
  • Reviews (14)
  • Snippets (24)
  • Techniques (52)

Popular Tags

Advanced Custom Fields Blogging Child Themes Content Marketing CSS Customer Service Custom Fields Custom Post Types Diagnostics Domain Names Facebook FooGallery Genesis Hosting HTML Images iPhone Libra Live Chat Marketing Media MemberPress MemberPress Courses Membership Sites Mobile-Friendly MySQL Photo Gallery php Pinterest Plugins Post Formats Pricing Project Management SEBA SEO Seth Godin Shortcodes Social Networking Surveys Taxonomies Twitter Video Web design Web forms WordPress

Footer

Background

Web Sites | WordPress Support | Web Applications.

Formally trained in liberal arts and education (I have a B.A. in Government from Harvard and studied Secondary Education at Rutgers Graduate School), I have honed my skills in the communication arts and sciences as a teacher, trainer, instructional designer, writer, photographer, calligrapher, helpdesk manager, database programmer, and multimedia developer.

(I've also been a group counselor, waiter, bartender, bicycle messenger boy, computer salesman, carpenter's helper, financial analyst, and school board president.)

Tech

Systems since 1983.
Web sites since 1994.
PHP since 2001.
WordPress since 2007.

Contact

Book Meeting
770-772-5134
Email Jeff
Send Money
All Ways

Copyright 2026, nSiteful Web Builders, Inc.

Cookies Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
  • Manage options
  • Manage services
  • Manage {vendor_count} vendors
  • Read more about these purposes
View preferences
  • {title}
  • {title}
  • {title}
https://iframe.mediadelivery.net/embed/392008/42d18bc1-2adc-4741-b733-053d08d09c32
https://vz-000c5976-3ab.b-cdn.net/42d18bc1-2adc-4741-b733-053d08d09c32/play_720p.mp4

Receive occasional emails from Jeff