Skip to main content

MembershipPriceRepository

\Benecaster\Membership\MembershipPriceRepository

Class Premium

Data access for the billing cadences attached to a built-in membership tier. One record is one cadence: a label, an interval (unit plus count), an amount, a currency, and the Stripe Price IDs minted for it in each keyset.

A tier is one Stripe Product with N Prices hanging off it, and this repository owns that child collection. A tier with no prices is legal and is deliberately hidden from benecaster_subscribe.

You rarely construct this directly. MembershipTierRepository takes it as a dependency and cascades through it, so writing a tier with a prices[] sub-array is the normal path. Reach for this class when you are manipulating cadences on a tier that already exists — adding a quarterly option to a live tier, for example.

Methods

Method Visibility Since Description
find_by_tier( int $tier_id ): array Public All cadences for a tier, in sort order. Returns an empty array for a tier with no prices — which is a valid state, not an error.
find( int $price_id ): ?array Public A single cadence by ID, or null when it does not exist.
find_default_for_tier( int $tier_id ): ?array Public The row flagged is_default for this tier — the cadence pre-selected on the subscription page. Null when the tier has no prices.
insert( array $price ): int Public Creates a cadence and returns its ID. Fires benecaster_membership_price_created, which is what triggers Stripe Price minting — so a row inserted through this method gets its Stripe IDs asynchronously, not inline.
update( int $price_id, array $price ): bool Public Updates a cadence. Any change to amount_cents or currency nulls stripe_price_id_test and stripe_price_id_live automatically — see the notes below, this behaviour is load-bearing.
delete( int $price_id ): bool Public Removes one cadence and fires benecaster_membership_price_deleted, which archives the corresponding Stripe Price. Existing subscribers on that cadence are unaffected — archiving a Stripe Price stops new sign-ups, it does not cancel subscriptions.
delete_by_tier( int $tier_id ): int Public Removes every cadence for a tier and returns the count deleted. Called by MembershipTierRepository::delete() as a cascade.
set_default_for_tier( int $tier_id, int $price_id ): bool Public Marks one row as the tier's default and clears the flag on its siblings in the same operation, so a tier can never end up with two defaults or none.

Hooks Fired

  • benecaster-membership-price-created
  • benecaster-membership-price-deleted

Notes

update() nulls the Stripe Price IDs on any amount or currency change, on purpose. Stripe Prices are immutable. If the stored ID survived an amount change, the plugin would happily go on charging new subscribers the old amount while the admin screen displayed the new one — the plan_price_mismatch defect class. Nulling the IDs forces a fresh mint before the cadence can be sold again.

The practical consequence: after changing an amount, there is a brief window where the row has no Stripe Price ID and that cadence cannot be checked out. Code that reads stripe_price_id_{test,live} must handle null rather than assuming a value is present.

Existing subscribers are never re-priced by any of this. They remain on the Stripe Price they signed up against.