benecaster_subscription_expired
Fires when a membership LAPSES — it ran out and was not renewed: a fixed-term plan reaching its end, or renewals that failed until the membership plugin (or Stripe, for built-in memberships) gave up. Use it to tell a lapse from a deliberate cancellation — a “your card stopped working” win-back message rather than a “sorry to see you go” one.
⚠ It fires IN ADDITION to benecaster_subscription_cancelled, never instead, and after it. Every listener on the cancelled hook — the cancellation email, webhooks — keeps working unchanged. It fires only when the subscriber holds no remaining tier on the show; an expiry reported while another tier is still active (MemberPress expires each period’s transaction even on a subscription that renewed) is not a lapse and fires nothing.
Which plugin events count as a lapse: Restrict Content Pro expired; Paid Memberships Pro’s expiry run; MemberPress transaction-expired; WooCommerce Subscriptions expired; built-in memberships whose Stripe subscription was deleted with reason payment_failed.
Win back members whose membership lapsed, not the ones who chose to leave
A lapse (a fixed term ran out, renewals gave up) and a cancellation are different conversations. benecaster_subscription_cancelled fires for both; benecaster_subscription_expired fires only for the lapse, straight after it.
benecaster_subscription_cancelled fires for lapses too, and before expired — so a “you cancelled” message sent from it reaches lapsed members as well. Treat cancelled as “ended, reason unknown” and put lapse-specific messaging on expired.
Custom bridges must report the lapse — pass 'expired' as the third argument of the on_subscription_cancelled() callback — or this never fires for their members.
<?php
add_action( 'benecaster_subscription_expired', function ( int $user_id, int $show_id, string $tier_slug ): void {
$user = get_userdata( $user_id );
if ( ! $user ) {
return;
}
// "Your card stopped working" rather than "sorry to see you go".
my_esp_add_tag( $user->user_email, 'lapsed-' . $tier_slug );
}, 10, 3 );
Parameters
| Name | Type | Default | Description |
|---|---|---|---|
$user_id |
int |
— | WordPress user ID |
$show_id |
int |
— | ID of the show |
$tier_slug |
string |
— | The tier the subscriber held, read from their token before it was revoked (empty when they had no token) |
Notes
A third-party bridge reports a lapse by passing 'expired' as the third argument of its on_subscription_cancelled() callback.
Need this built rather than just documented? See our services →