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
- 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
- There are three membership “families”: All Video Courses; All Show Recordings; and a Courses & Shows Bundle.
- Each membership family has two plans: Monthly and Annual.
- 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:

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.

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
- 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.phpfile in your site's child theme directory - use a code snippets plugin such as Code Snippets
- add it to the
functions.phpfile 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.

Leave a Reply