By default, Paid Memberships Pro grants every new member a full membership term starting on their checkout date. That works well for memberships that begin whenever a member is ready, but it does not fit sites that sell access tied to a fixed external cycle, such as a school semester, a sports season, or a calendar quarter.

This code recipe lets members tell you at checkout how far into the current term they already are, then automatically shortens their expiration date to match the time remaining in that term. A member who joins three months into a ten-month season is given seven months of access, not a full term.

Set a Level to Expire Based on Remaining Time in Term

Do You Need This Recipe?

This recipe is useful if any of the following apply to your site:

  • You sell membership access tied to a fixed term that everyone shares, such as a school year, a season, or a calendar quarter.
  • You want every member’s access to end on the same date, regardless of when they joined.
  • You want to give members a way to indicate where they are in the cycle at checkout, rather than charging the same price for less time without acknowledgement.

If your memberships always run for a full term from the checkout date, or you handle prorating with a discount code rather than a shorter expiration, this recipe is not the right fit.

About the Code Recipe

The recipe does two things. First, it adds a How far into the term are you? select field to the membership checkout page for the levels you specify. The field offers values from 1 month to 9 months. Second, it filters the $level object during checkout, reads the value the member chose, and sets the expiration date to the remaining time in a 10-month term.

For example, if a member selects 2 Months, the recipe sets their expiration to 8 months from the checkout date. The total term length and the option list are easy to change for your own cycle.

Note: The example was originally written for a pregnancy-tracking site that sold a 9-month plan with monthly checkpoints. The pattern works for any fixed-cycle membership, including academic semesters, sports seasons, and subscription boxes that ship on a shared schedule.

Understanding the pmpro_checkout_level Filter

The pmpro_checkout_level filter runs during membership checkout after the form is submitted, but before the level is applied to the member’s account. It passes the $level object that Paid Memberships Pro is about to use to create the membership, and your callback returns it (modified or not).

This is the right hook for adjusting expiration dates because anything you change on the level object, including expiration_number and expiration_period, is applied to that one member without affecting the level’s defaults in the WordPress admin.

The Code Recipe

Adding the Recipe to Your Website

You can add this recipe to your site by creating a custom plugin or using the Code Snippets plugin available for free in the WordPress repository. Read this companion article for step-by-step directions on either method.

How to Customize This Code Recipe

Change Which Levels Show the Term Field

The recipe shows the term field on level IDs 1 and 2 by default in the PMPro_Field definition. To change which levels show the field, update the levels array on line 31. You can find your level IDs in Memberships > Settings > Levels in the WordPress admin. The ID appears in the URL when you click Edit next to a level.

Change the Total Term Length

The recipe assumes a 10-month term and offers options from 1 to 9 months. To use a different length, do two things in the snippet:

  • Update the options array passed into the PMPro_Field definition on line 33 so the dropdown lists the months that apply to your cycle.
  • Update the $total_months variable in my_pmpro_checkout_level_set_expiration_from_term() on line 66 to match the full length of your cycle.

For example, for a 4-month semester, set $total_months to 4 and offer options from 1 to 3 months in the dropdown.

Create the Field in the User Fields UI Instead

If you would rather manage the term-progress field through the User Fields settings page instead of in code, you can build the same select field there and remove the my_pmpro_add_term_user_field() function from the snippet. Keep the my_pmpro_checkout_level_set_expiration_from_term() function. The expiration logic does not depend on how the field was created, only on the terms field name being submitted with the checkout form.

Free Course: Membership Site Development—The Basics

Develop a deeper understanding of membership site development in this beginner-level course. Learn how to make your site work better, save yourself time and money, and improve your site's performance.

Featured Image for Membership Site Development Course: The Basics


Was this article helpful?
YesNo