Skip to content

Instantly share code, notes, and snippets.

@messica
Created May 23, 2019 18:12
Show Gist options
  • Save messica/09d6bb4bdf54b0ee51d031d98c588a44 to your computer and use it in GitHub Desktop.
Save messica/09d6bb4bdf54b0ee51d031d98c588a44 to your computer and use it in GitHub Desktop.
Prorate initial payment based on subscription delay.
<?php
/**
* Prorate initial payment based on subscription delay.
*
* Requires Subscription Delay and Proration Add Ons.
*/
function my_pmpro_checkout_level( $level ) {
// Only continue if Subscription Delays and Proration Add Ons are activated.
if ( ! function_exists( 'pmprosd_convert_date' ) || ! function_exists( 'pmprorate_trim_timestamp' ) ) {
return $level;
}
// Only continue for new members. (no "success" orders for this level)
global $current_user;
if ( ! empty( $current_user ) ) {
$order = new MemberOrder();
$order->getLastMemberOrder( $current_user->ID );
if ( ! empty( $order ) && $order->membership_id == $level->id ) {
return $level;
}
}
// Get subscription start date for level.
$subscription_delay = get_option( 'pmpro_subscription_delay_' . $level->id );
if ( empty( $subscription_delay ) ) {
return $level;
}
if ( ! is_numeric( $subscription_delay ) ) {
$start_date = pmprosd_convert_date( $subscription_delay );
} else {
$start_date = date( 'Y-m-d', strtotime( '+ ' . intval( $subscription_delay ) . ' Days', current_time( 'timestamp' ) ) ) . 'T0:0:0';
}
// Prorate initial payment.
$next_payment_date = pmprorate_trim_timestamp( strtotime( $start_date, current_time( 'timestamp' ) ) );
$payment_date = pmprorate_trim_timestamp( strtotime( "-{$level->cycle_number} {$level->cycle_period}", $next_payment_date ) );
$today = pmprorate_trim_timestamp( current_time( 'timestamp' ) );
$days_in_period = ceil( ( $next_payment_date - $payment_date ) / 3600 / 24 );
// if no days in period (next payment should have happened already) return level with no change to avoid divide by 0
if ( $days_in_period <= 0 ) {
return $level;
}
$days_passed = ceil( ( $today - $payment_date ) / 3600 / 24 );
$per_passed = $days_passed / $days_in_period; // as a % (decimal)
$per_left = 1 - $per_passed;
$credit = $level->initial_payment * $per_passed;
$level->initial_payment = round( $level->initial_payment - $credit, 2 );
// just in case we have a negative payment
if ( $level->initial_payment < 0 ) {
$level->initial_payment = 0;
}
// Make sure we don't run other proration code if we get to this point.
remove_filter( 'pmpro_checkout_level', 'pmprorate_pmpro_checkout_level', 10, 1 );
return $level;
}
add_filter( 'pmpro_checkout_level', 'my_pmpro_checkout_level', 5 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment