Billing Engine for Laravel
Roll out a plan entitlement
Roll out a plan entitlement
When a plan-wide entitlement change lands, applying it org-by-org with a per-org
cache-bust would storm the cache on a large plan. EntitlementRollout splits the
cohort so the common case is cheap.
Apply the change
use Cbox\Billing\Entitlement\Rollout\Contracts\EntitlementRollout;
use Cbox\Billing\Entitlement\Rollout\ValueObjects\PlanEntitlementChange;
$change = new PlanEntitlementChange(
id: 'chg-2026-07',
plan: 'pro',
grants: $newGrants, // the entitlement grants the plan now confers
);
$report = $rollout->apply($change, cohort: $orgIds);
$report; // RolloutReport: how many applied via the bulk path vs individually
Under the hood:
- Orgs without an override are written in chunks (
entitlement.rollout.chunk_sizeper transaction), each chunk one atomic transaction, with no per-org cache-bust — invalidation rides the hot-path cache TTL. A 100k-org plan does not storm the cache. - Orgs with an override bypass the bulk path: written individually and cache-busted immediately, because their state genuinely diverges from the plan default.
Every application is recorded to the RolloutJournal (durable
DatabaseRolloutJournal) as audit rows.
Audit for missing entitlements
Separately, sweep for orgs that should have an entitlement but don't — a cohort of gaps is an outage worth surfacing rather than denying one request at a time:
php artisan billing:entitlements:audit