Skip to main content

Listener Support Hooks and Shortcode Reference

Developer reference for the Listener Support system. Full documentation for each hook and shortcode — parameters, return types, and usage examples — lives in the dedicated CPT entries linked below.

A note on amounts

Every amount passed through a Stripe-mode hook is an integer in the smallest currency unit — 500 is $5.00 in USD, and 500 is ¥500 in JPY. None of them is a float in major units.

This matters more than it sounds. A guard written as $amount >= 5.00 compares 500 against 5.00, passes, and admits a 50-cent donation through what its author believed was a $5 minimum. Nothing warns you: the filter runs, returns a value, and the donation succeeds. Read the currency from the settings rather than dividing by 100, because minor units are not hundredths in every currency.

The exception is benecaster_donation_received, which fires from the webhook after payment and receives a float in major units. The two conventions coexist deliberately — the webhook reports settled money, the intent-side hooks handle a submission — so check which side of the payment you are on.

Filters — prompt and display

Hook Description
benecaster_listener_support_enabled Controls whether the Listener Support prompt renders for the current request. Return false to suppress.
benecaster_listener_support_output Filters the fully rendered HTML of a Listener Support variant before it is returned to the caller. Fires even when the output is empty. Its arguments are ( $html, $style, $show_id ) on both the link and Stripe paths — $show_id is 0 when there is no show context, so don’t type-hint the third argument as an array.
benecaster_listener_support_button_label Filters the button label text.
benecaster_listener_support_message Filters the message body text. Returning an empty string hides the message element.
benecaster_listener_support_button_position Filters the corner anchor for the floating-button variant. Accepts bottom-right, bottom-left, top-right, top-left.
benecaster_donor_enrollment_label Filters the label on the donor mailing-list opt-in checkbox.

Filters — donation amounts (Stripe mode)

Hook Description
benecaster_donation_suggested_amounts Filters the preset amount buttons — int[], minor units. This filter owns the buttons, and it is the only thing that does.
benecaster_donation_minimum_amount Filters the floor a supporter’s typed amount must clear, per show. The supported way to enforce a donation minimum.
benecaster_donation_amount Filters the amount immediately before it is sent to Stripe. Changes what the supporter is charged without telling them — not a way to enforce a minimum.

The minimum can never veto a show’s own suggested amounts, and no filter can make it. Benecaster matches the suggested list first, deliberately: a floor that could disable a button the podcaster can see on their own page would fail with the explanation nowhere. To remove a suggested amount, remove it with benecaster_donation_suggested_amounts.

Filters — donation flow (Stripe mode)

Hook Description
benecaster_should_create_donation_intent Blocks PaymentIntent creation. Runs after amount validation and before Stripe is contacted. Takes four parameters — a callback declaring three silently never receives the currency.
benecaster_donation_decline_alert_thresholds Tunes the per-show decline-rate warning. Both halves matter — see below.
benecaster_donation_confirmation_message Filters the thank-you message HTML on the confirmation screen.

Filters — recording a donation report

Hook Description
benecaster_listener_support_accept_donation Runs before a donation report sent to POST /listener-support/donations is written. Return false and nothing is recorded, benecaster_listener_support_donation_logged does not fire, and the caller gets 403 donation_rejected. $submission carries show_id, platform, canonical_platform, verified, user_id, donor_email, amount (major units), currency, reference, note, display_name and donated_at (UTC). See the recipe Refuse fake donation reports.

Actions

Hook Description
benecaster_before_donation_form Fires during shortcode rendering, immediately before the donation form markup.
benecaster_after_donation_form Fires immediately after the donation form markup.
benecaster_donation_received Fires on payment_intent.succeeded after the donation is recorded and the thank-you email queued. The donation is already committed — not a place to prevent recording.
benecaster_donation_payment_failed Fires on payment_intent.payment_failed for a donation. The only way to observe a declined donation — see below.
benecaster_before_donation_confirmation Fires before the confirmation screen HTML.
benecaster_after_donation_confirmation Fires after the confirmation screen HTML.
benecaster_listener_support_donation_logged Fires after a link-mode donation reference row is written. Use to sync records to a CRM, send a Slack notification, or trigger any follow-up process. The row is already written: to stop one being recorded, use benecaster_listener_support_accept_donation below.
benecaster_donor_enrolled_as_follower Fires after a donor who opted in is provisioned as a free follower. Does not fire when an existing user is skipped.
benecaster_donor_data_erased Fires whenever donation records are anonymised (identity cleared, amount and date kept; no row is removed): from the donor’s own erasure request, from Tools → Erase Personal Data, and when a WordPress account is deleted. Carries the email and the number of rows anonymised, and fires with a count of 0 too, so check the count.

On the two confirmation actions, $amount is always 0.0. The screen is rendered before any amount is known, so the parameter is a placeholder rather than the donation’s value — use benecaster_donation_received when you need the real figure.

Observing declined donations

benecaster_donation_payment_failed is the only way to see a declined donation anywhere in Benecaster. No failure row is written to any table: the donations table is money received, and every reader of it — the admin donation list, the dashboard panel, the Analytics Dashboard add-on — would count a failure row as a donation. There is no failure table and none is planned, so a decline not captured at this action is not recoverable afterwards.

Two conditions govern whether it fires at all. It ignores any Stripe intent without a show ID in its metadata, so membership and buy-up failures on the same Stripe account never reach it. And it depends on the show’s Stripe webhook being subscribed to payment_intent.payment_failed — a show missing that event produces no declines, no counters and no warning, so silence there is absence of data rather than health.

When tuning benecaster_donation_decline_alert_thresholds, keep min_attempts rather than filtering on rate alone. One genuinely expired card on a quiet day is a 100% decline rate, and an alert that fires on that is one the podcaster learns to ignore. Benecaster clamps the floor to a minimum of 1 for that reason.

Neither hook detects card testing. They raise the cost and report the shape; Stripe Radar’s card-testing rules are what recognise an attack, and they live on the podcaster’s own Stripe account.

Shortcode

Shortcode Description
[benecaster_listener_support] Renders a Listener Support prompt. Supports link-mode and Stripe-mode styles. Available on all plans including free.

See Also

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