Skip to content

Instantly share code, notes, and snippets.

@dwanjuki
Created July 17, 2026 07:50
Show Gist options
  • Select an option

  • Save dwanjuki/0b5ebdcb3c7b21a04dddf87d516882aa to your computer and use it in GitHub Desktop.

Select an option

Save dwanjuki/0b5ebdcb3c7b21a04dddf87d516882aa to your computer and use it in GitHub Desktop.
<?php
/**
* Charge the level's billing amount instead of the initial payment when an old (expired or cancelled)
* member checks out again for the same level within a set number of years of their membership ending.
*
* 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:
* https://www.paidmembershipspro.com/create-a-plugin-for-pmpro-customizations/
*/
/**
* Check if the returning member price should apply for a user checking out for a level.
*
* @param object $level The level being checked out for.
* @return bool True if the user is an old member of this level within the grace period.
*/
function my_pmpro_returning_member_price_applies( $level ) {
global $wpdb;
// Set the level IDs this logic applies to.
$level_ids = array( 1 );
// Set the number of years after a membership ends that the returning member price applies.
$years = 3;
// Must be logged in for us to look up their old memberships.
if ( ! is_user_logged_in() ) {
return false;
}
// Only apply to the specified levels.
if ( ! in_array( (int) $level->id, $level_ids, true ) ) {
return false;
}
// Only apply to recurring levels. Otherwise, the checkout would become free.
if ( empty( $level->billing_amount ) ) {
return false;
}
// Don't apply if the user currently has this level. This is for old members only.
if ( pmpro_hasMembershipLevel( $level->id ) ) {
return false;
}
// Get the most recent end date for this user's old memberships for this level.
$enddate = $wpdb->get_var(
$wpdb->prepare(
"SELECT enddate FROM $wpdb->pmpro_memberships_users
WHERE user_id = %d
AND membership_id = %d
AND status IN ( 'expired', 'inactive', 'cancelled', 'admin_cancelled' )
AND enddate IS NOT NULL
AND enddate <> '0000-00-00 00:00:00'
ORDER BY enddate DESC
LIMIT 1",
get_current_user_id(),
$level->id
)
);
// The user was never a member of this level, or we have no end date on record.
if ( empty( $enddate ) ) {
return false;
}
// Check if the membership ended within the grace period.
return strtotime( $enddate ) >= strtotime( '-' . $years . ' years', current_time( 'timestamp' ) );
}
/**
* Swap the initial payment for the billing amount at checkout for returning members.
*/
function my_pmpro_returning_member_checkout_level( $level ) {
global $discount_code;
// Let discount codes take priority.
if ( ! empty( $discount_code ) ) {
return $level;
}
if ( my_pmpro_returning_member_price_applies( $level ) ) {
$level->initial_payment = $level->billing_amount;
}
return $level;
}
add_filter( 'pmpro_checkout_level', 'my_pmpro_returning_member_checkout_level' );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment