Skip to main content

React to subscription lifecycle events from the built-in membership system

Premium Intermediate

Benecaster registers four handlers on the shared Stripe webhook and re-emits each Stripe event as a normalized Benecaster action carrying (string $stripe_subscription_id, \Stripe\Event $event). Add-ons should hook these routing actions instead of registering duplicate webhook handlers — it keeps per-event payload parsing in one place. Important: …_invoice_payment_failed listeners MUST NOT revoke a subscriber’s token or feed access — Benecaster policy lets Stripe exhaust its retry schedule. Access ends on …_subscription_deleted, or on …_subscription_updated when the status moves to unpaid (Stripe’s mark as unpaid retry setting, where no deletion ever comes).

Use the $stripe_subscription_id argument rather than anything read off $event. The event is rendered at the Stripe API version of the podcaster’s webhook endpoint, so on an endpoint at 2025-03-31.basil or later an invoice has no top-level subscription and a subscription has no top-level current_period_end. Benecaster resolves the argument from either shape.

Code

<?php
add_action(
    'benecaster_stripe_membership_invoice_payment_failed',
    function ( string $stripe_subscription_id, \Stripe\Event $event ): void {
        // Do not revoke feed access here — Benecaster policy is to let Stripe
        // exhaust its retry schedule. Use this hook for diagnostics,
        // creator notifications, CRM updates, etc.
        my_addon_log_payment_retry( $stripe_subscription_id, (int) $event->created );
    },
    10,
    2
);

View on GitHub →

Hooks Used

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