Skip to main content

React to subscriber-initiated lifecycle events from the native billing portal

Premium Intermediate

When a subscriber manages their own subscription in Benecaster’s billing portal, two different kinds of event describe it, and mixing them up is the usual source of bugs here.

Portal events say what a person just did. They fire at the moment of the click and identify the subscriber who did it. Webhook events say what Stripe eventually settled on, which can be much later and has no actor attached. If you want to send “we’re sorry to see you go” or write who cancelled to an audit log, you need the portal event — the webhook cannot tell you who was at the keyboard.

Three portal events are available:

  • Cancellation requested — the subscriber has asked to cancel. They have not lost access. The subscription is set to stop at the end of the period they have already paid for, and the separate cancellation event still fires from Stripe when that period actually ends. Treat this as intent, not as the ending.

  • Resumed — they changed their mind before the period ended and called off a pending cancellation. Worth catching if you acted on the request above.

  • Payment method updated — fires once the change has fully succeeded, so you are not reacting to a card that did not take.

Code

<?php
// Log every subscriber-initiated cancellation request for retention analytics.
add_action( 'benecaster_subscription_cancellation_requested', function ( int $user_id, int $show_id, string $stripe_subscription_id ): void {
    my_addon_retention_log( [
        'event'        => 'cancellation_requested',
        'user_id'      => $user_id,
        'show_id'      => $show_id,
        'requested_at' => current_time( 'mysql', true ),
    ] );
}, 10, 3 );

// Schedule a "win-back" follow-up 24 hours after a cancellation request.
add_action( 'benecaster_subscription_cancellation_requested', function ( int $user_id, int $show_id ): void {
    wp_schedule_single_event( time() + DAY_IN_SECONDS, 'my_addon_send_winback_email', [ $user_id, $show_id ] );
}, 10, 2 );

// Cancel any scheduled win-back flow when a subscriber resumes.
add_action( 'benecaster_subscription_resumed', function ( int $user_id, int $show_id ): void {
    wp_clear_scheduled_hook( 'my_addon_send_winback_email', [ $user_id, $show_id ] );
}, 10, 2 );

View on GitHub →

Hooks Used

Need this built rather than just documented? See our services →