React to subscription lifecycle events from the built-in membership system
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
);
Hooks Used
Need this built rather than just documented? See our services →