Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kimcoleman/85cfe2cccb02a2bda0932b7e3c1169ad to your computer and use it in GitHub Desktop.
Save kimcoleman/85cfe2cccb02a2bda0932b7e3c1169ad to your computer and use it in GitHub Desktop.
Let members switch payment methods but preserve their current subscription price and renewal date.
<?php
/**
* Get the next payment date for a user's level inclusive of subscriptions and expiration dates.
*
* If the current user has a subscription for a passed level ID, return the next payment date for that subscription.
* Otherwise, if the user has an expiration date set for the level, return that.
* Otherwise, return null.
*
* @param int $level_id The level ID to check for.
* @return int|null The next payment date/expiration date as a timestamp or null.
*/
function my_pmpro_renew_or_change_payment_method_get_next_payment_date( $level_id ) {
global $current_user;
// Bail if not logged in.
if ( empty( $current_user->ID ) ) {
return null;
}
// See if the user has a subscription or level for the passed level ID.
$current_subscriptions = PMPro_Subscription::get_subscriptions_for_user( $current_user->ID, $level_id );
$current_level = pmpro_getSpecificMembershipLevelForUser( $current_user->ID, $level_id );
if ( ! empty( $current_subscriptions ) ) {
// Return the next payment date for the subscription.
$next_payment_date = $current_subscriptions[0]->get_next_payment_date();
} elseif ( ! empty( $current_level ) ) {
// Return the expiration date for the level.
$next_payment_date = $current_level->enddate;
}
// If we do not have a next payment date, return null.
if ( empty( $next_payment_date ) ) {
return null;
}
// If we have a subscription start date in the past, return null.
if ( $next_payment_date < current_time( 'timestamp' ) ) {
return null;
}
// Ok, we can adjust the start date.
return $next_payment_date;
}
/**
* If checking out for same level with active membership, set initial payment to $0 and start subscription on next payment date OR expiration date.
*/
function my_pmpro_renew_or_change_payment_method_checkout_level( $level ) {
global $current_user;
// Bail if PMPro is not active.
if ( ! class_exists( 'PMPro_Subscription' ) ) {
return $level;
}
// Return early if using a discount code
if ( ! empty( $level->discount_code ) || ! empty( $_REQUEST['discount_code'] ) ) {
return $level;
}
// Assume we do not need to adjust the checkout level.
$subscription_start_date = my_pmpro_renew_or_change_payment_method_get_next_payment_date( $level->id );
// If we do not have a subscription start date, return.
if ( empty( $subscription_start_date ) ) {
return $level;
}
// Ok, we can adjust the level.
// Charge them nothing today.
$level->initial_payment = 0;
// Set the billing start date on the checkout level.
$level->profile_start_date = date( 'Y-m-d H:i:s', $subscription_start_date );
// Get their active or last active subscription.
$last_subscription = PMPro_Subscription::get_subscription(
array(
'user_id' => $current_user->ID,
'membership_level_id' => $level->id
)
);
// If they have a last subscription, set the billing amount.
if ( ! empty( $last_subscription ) ) {
$level->billing_amount = $last_subscription->get_billing_amount();
}
return $level;
}
add_filter( 'pmpro_checkout_level', 'my_pmpro_renew_or_change_payment_method_checkout_level', 10 );
/**
* Change the Level Cost Text on the checkout page
*/
function my_pmpro_renew_or_change_payment_method_level_cost_text( $cost, $level ) {
global $pmpro_pages;
// Bail if PMPro is not active.
if ( ! function_exists( 'pmpro_isLevelRecurring' ) ) {
return $cost;
}
// Bail if this is not the checkout page.
if ( empty( $pmpro_pages ) || empty( $pmpro_pages['checkout'] ) || ! is_page( $pmpro_pages['checkout'] ) ) {
return $cost;
}
// Return early if using a discount code
if ( ! empty( $level->discount_code ) || ! empty( $_REQUEST['discount_code'] ) ) {
return $cost;
}
// Bail if the level is not recurring.
if ( ! pmpro_isLevelRecurring( $level ) ) {
return $cost;
}
// Assume we do not need to adjust the cost text.
$subscription_start_date = my_pmpro_renew_or_change_payment_method_get_next_payment_date( $level->id );
// If we do not have a subscription start date, bail.
if ( empty( $subscription_start_date ) ) {
return $cost;
}
// Ok, we can adjust the cost text.
$cost .= 'Your first subscription payment will be processed on ' . date_i18n( get_option( 'date_format' ), $subscription_start_date ) . '.';
return $cost;
}
add_filter( 'pmpro_level_cost_text', 'my_pmpro_renew_or_change_payment_method_level_cost_text', 10, 2 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment