Skip to main content

Show or hide content based on whether a subscriber owns a buy-up

Premium Beginner

Buy-ups are optional add-ons subscribers can purchase on top of their existing plan — things like transcripts, bonus content, or extended access — without upgrading to a higher tier. Use benecaster_user_has_buyup() to check whether the current subscriber owns a specific buy-up, then show or hide content in your template accordingly.

The example shows the pattern in a template override: render the premium block for subscribers who own the buy-up, and show an upsell shortcode to those who don’t.

Gating the feed as well as the page

You usually do not need code for this. A buy-up’s token_type is a pseudo-tier slug: tick the buy-up on an episode’s Access tab and Benecaster writes that slug into the episode’s availability rows, then appends the token types a subscriber holds to their resolved slug list at feed-request time. The episode compiles into their feed exactly as a tier-scheduled one would. Reach for the helper above when you are gating your own markup — a template block, a shortcode, a page — not when you are gating an episode.

Gating is additive. A buy-up adds an unlock path on top of the tier schedule and never removes one. To sell an episode exclusively, leave every tier unscheduled and tick the buy-up — then the buy-up’s slug is the only one carrying it.

A no-code default now exists for the common case. If every new episode on a show should require the same buy-up, set it once on Shows → [show] → Subscription → Buy-up Defaults rather than ticking it on every episode by hand — that seeds _benecaster_required_buyups at creation with no code at all. This recipe’s filter/function approach is still the right tool for anything the admin field can’t express: a per-user requirement, a requirement computed at render time, or gating something other than an episode.

A purchase or cancellation needs no cache invalidation. A grant changes which slugs a subscriber resolves to, not the contents of any slug’s feed, so there is nothing to flush. Cache entries scale with the number of distinct buy-ups on a show, never with the combinations subscribers hold.

benecaster_feed_before_render’s $tier_slug argument is always the base tier, never an appended buy-up slug. Index 0 of the resolved list is the base tier by construction — it is also the analytics snapshot written to the token row — so a callback that reads $tier_slug to decide whether a subscriber holds a buy-up will never see one. Call benecaster_user_has_buyup() instead.

Code

<?php
// Inside a theme template part (e.g. episode/single.php override).
if ( benecaster_user_has_buyup( 0, $transcripts_buyup_id, $show_id ) ) {
    // Render the transcript download block.
    echo do_shortcode( '[my_transcript_download episode="' . $episode_id . '"]' );
} else {
    // Render the "Add transcripts to your plan" upsell.
    echo do_shortcode( '[benecaster_buyup_upsell buyup="' . $transcripts_buyup_id . '"]' );
}

View on GitHub →

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