You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(checkout): allow billing-period switches as scheduled downgrades
Previously switching from a longer billing cycle (yearly) to a shorter
one (monthly) was blocked with 'You already have an active yearly
agreement.' regardless of whether the customer had the same plan or a
different one. This prevented legitimate billing-period changes.
Root cause: class-cart.php lines 1347-1362 detected 'old_price_per_day
< new_price_per_day && old_cycle_days > new_cycle_days' and hard-blocked
with a WP_Error instead of scheduling the change.
Fix:
- Remove the hard-block. Add $is_period_switch_to_shorter flag that
covers the same condition and merges it into the existing downgrade
branch (lines 1370+). The change is now scheduled for the next renewal
date exactly like any other downgrade — no payment collected, cart
total $0.
- Fix defensive null guard at get_billing_next_charge_date() line 2752:
add null check on $membership before calling ->is_active(), matching
the guard already present in get_billing_start_date() line 2709.
Tests: 4 new tests in Cart_Test covering monthly→yearly upgrade,
yearly→monthly downgrade (same plan), yearly→monthly downgrade (different
plan), and null-membership guard on get_billing_next_charge_date().
All 121 Cart_Test tests pass.
Fixes#888
$this->assertFalse($cart->get_errors()->has_errors(), 'Switching monthly→yearly must not produce an error. Got: ' . implode(', ', $cart->get_errors()->get_error_messages()));
2912
+
2913
+
// Switching to a more expensive annual commitment is an upgrade.
// Must NOT produce an error (previously blocked with "You already have an active yearly agreement.").
2965
+
$this->assertFalse($cart->get_errors()->has_errors(), 'Switching yearly→monthly must not produce an error. Got: ' . implode(', ', $cart->get_errors()->get_error_messages()));
2966
+
2967
+
// Should be a scheduled downgrade, not a hard block.
$this->assertFalse($cart->get_errors()->has_errors(), 'Switching from yearly plan to monthly plan must not produce an error. Got: ' . implode(', ', $cart->get_errors()->get_error_messages()));
3020
+
3021
+
// The switch to a shorter cycle must be a downgrade (scheduled for next renewal).
0 commit comments