Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save messica/36d98f94ae878dd963ad to your computer and use it in GitHub Desktop.
Save messica/36d98f94ae878dd963ad to your computer and use it in GitHub Desktop.
Prorated payments
<?php
/*
Prorated payments. When a member chooses to upgrade,
he should be charged a pro-rated amount for the new membership level immediately,
and the payment date should stay the same.
Assumes initial payments are equal to billing amount.
Add this code to your active theme's functions.php or include this in a custom plugin.
*/
function my_pmpro_checkout_level($level)
{
//does the user have a level already?
if(pmpro_hasMembershipLevel())
{
//get current level
global $current_user, $wpdb;
$clevel = $current_user->membership_level;
//get their payment date
$morder = new MemberOrder();
$morder->getLastMemberOrder();
$payment_date = date("Y-m-d", $morder->timestamp);
$payment_day = intval(date("j", $morder->timestamp));
//when would the next payment be
$next_payment_date = date('Y-m-d', pmpro_next_payment($current_user->ID));
//today
$today = date("Y-m-d");
//how many days in this period
$days_in_period = $wpdb->get_var("SELECT DATEDIFF('" . $next_payment_date . "','" . $payment_date . "')");
//how many days have passed
$days_passed = $wpdb->get_var("SELECT DATEDIFF('" . $today . "','" . $payment_date . "')");
//what percentage
$per_passed = $days_passed / $days_in_period; //as a % (decimal)
$per_left = 1 - $per_passed;
/*
Now figure out how to adjust the price.
(a) What they should pay for new level = $level->billing_amount * $per_left.
(b) What they should have paid for current level = $clevel->billing_amount * $per_passed.
What they need to pay = (a) + (b) - (what they already paid)
*/
$new_level_cost = $level->billing_amount * $per_left;
$old_level_cost = $clevel->billing_amount * $per_passed;
$level->initial_payment = round($new_level_cost + $old_level_cost - $morder->total, 2);
//just in case we have a negative payment
if($level->initial_payment < 0)
$level->initial_payment = 0;
}
return $level;
}
add_filter("pmpro_checkout_level", "my_pmpro_checkout_level");
/*
If checking out for the same level, keep your old startdate.
Updated from what's in paid-memberships-pro/includes/filters.php to run if the user has ANY level
*/
function my_pmpro_checkout_start_date_keep_startdate($startdate, $user_id, $level)
{
if(pmpro_hasMembershipLevel()) //<-- the line that was changed
{
global $wpdb;
$sqlQuery = "SELECT startdate FROM $wpdb->pmpro_memberships_users WHERE user_id = '" . $wpdb->escape($user_id) . "' AND membership_id = '" . $wpdb->escape($level->id) . "' AND status = 'active' ORDER BY id DESC LIMIT 1";
$old_startdate = $wpdb->get_var($sqlQuery);
if(!empty($old_startdate))
$startdate = "'" . $old_startdate . "'";
}
return $startdate;
}
remove_filter("pmpro_checkout_start_date", "pmpro_checkout_start_date_keep_startdate", 10, 3); //remove the default PMPro filter
add_filter("pmpro_checkout_start_date", "my_pmpro_checkout_start_date_keep_startdate", 10, 3); //our filter works with ANY level
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment