Give higher tiers a longer window to re-enter payment details
The Promote to Bridge wizard collects a single grace-period length and applies it to everyone. That is usually right, but not always: a podcaster migrating a $2/month tier and a $50/month tier has more to lose from the second group churning during the transition, and may want to give them longer to act.
benecaster_promote_grace_length_days runs once per transferred row, inside the migration loop, at the moment the deadline is written — so the length can vary by tier, by billing interval, by how long the subscriber has been around, or by anything else on the row.
Notes
Returning 0 or a negative does not mean “no grace period”. The value is floored to one day after your callback runs, deliberately: a zero would write a deadline in the past, and the daily expiry cron would revoke that subscriber on its very next tick — cutting off the person you were migrating, which is the opposite of what a grace period is for. If you want someone excluded from the migration, do not promote them.
The filter applies to the initial set only, not to extend_grace_period(). When the podcaster types a number into the Extend field in Promotion History, that number is used as typed. Filtering it would make the panel report a change it did not make.
The grace_period_ends_at field in the wizard’s result payload is the baseline the podcaster typed, not a summary of what each row received. With this filter in play, individual rows can and will differ from it. Read the per-row deadlines from promote_grace_period_ends_at rather than from that one field.
$promotion is the subscription row being transferred — id, user_id, show_id, tier_slug, billing_interval, status and the rest of the row’s columns. $user_id duplicates $promotion['user_id'] for convenience. Return the incoming $days whenever you do not want to intervene, so you compose with other callbacks rather than overriding them.
Code
<?php
add_filter( 'benecaster_promote_grace_length_days', function ( int $days, array $promotion, int $user_id ): int {
$extra = [
'gold' => 90,
'silver' => 60,
];
// Annual subscribers get the longest window regardless of tier - they are
// the least likely to be watching their inbox on any given week.
if ( 'annual' === ( $promotion['billing_interval'] ?? '' ) ) {
return max( $days, 120 );
}
return $extra[ $promotion['tier_slug'] ] ?? $days;
}, 10, 3 );
Hooks Used
Need this built rather than just documented? See our services →