Manage Subscription Plans and Entitlements in Laravel with Laravel Entitlements
Last updated on by Paul Redmond
Laravel Entitlements tackles one of the more involved problems in SaaS development: modeling what a subscriber is allowed to do, how much of it they can use, and what happens when they hit a limit or switch plans.
Rather than rolling your own entitlement logic, this package gives you a structured approach built around plans, licenses, and consumption tracking. Here's a quick overview of what the package covers:
- Slot-based and pool-based consumption — slot strategies track one usage per subject (e.g., a specific device or seat), while pool strategies drain a shared counter (e.g., AI tokens or API credits)
- Polymorphic ownership — any Eloquent model can act as a subscriber by adding the
HasEntitlementstrait, making it straightforward to scope entitlements to teams, workspaces, or individual users - Plan catalog with billing options — plans support monthly/yearly billing cycles and can be configured as recurring or fixed-term, with items that allow per-assignment quantity overrides
- Domain events — the package dispatches events like
LicenseConsumed,ReleaseRequested, andLicenseReconciled, giving you integration points for billing webhooks, background jobs, or audit logging - Optional Filament v5 admin panel — a ready-made management interface for plans, categories, and licenses that can be dropped into an existing Filament project
Defining Entitlement Types
The package uses a PHP backed enum to define what kinds of entitlements exist in your app and which strategy each one uses. This means the consumption logic is tied to your domain vocabulary rather than generic configuration:
enum LicenseType: string implements EntitlementType{ case Device = 'device'; case AiTokens = 'ai_tokens'; case Seat = 'seat'; public function strategy(): EntitlementStrategy { return match ($this) { self::Device => new SlotStrategy(twoPhase: true), self::AiTokens => new PoolStrategy(), self::Seat => new SlotStrategy(), }; }}
The twoPhase: true option on the Device case is worth noting — it splits release into two steps (requestRelease() then confirmRelease()), which is useful when you need an external process (like revoking a device token) to complete before the slot is freed.
Consuming and Checking Entitlements
Once a plan is assigned to a subscriber, consuming an entitlement is a single method call:
// Slot-based: tie usage to a specific subjectEntitlements::consume($workspace, LicenseType::Seat, $user); // Pool-based: drain a set amount from the shared counterEntitlements::consume($workspace, LicenseType::AiTokens, $usage, amount: 1500);
Checking availability before consuming is just as direct:
Entitlements::can($workspace, LicenseType::AiTokens, 1500); // boolEntitlements::available($workspace, LicenseType::AiTokens); // remaining capacity
When capacity runs out, the package throws a NoEntitlementAvailableException, which you can catch and handle at the controller or middleware level.
Plan Transitions
Switching a subscriber between plans is handled through changePlan(), which supports both immediate switches and end-of-period transitions. The package validates the transition before persisting it, so subscribers won't lose capacity for usages already in flight when a downgrade is applied.
Installation
Install via Composer:
composer require masterix21/laravel-entitlements
Then publish and run the migrations:
php artisan vendor:publish --tag="laravel-entitlements-config"php artisan vendor:publish --tag="laravel-entitlements-migrations"php artisan migrate
The package requires PHP 8.2+ and Laravel 11 or higher. The optional Filament integration requires Filament v5.
You can find the full documentation and source code on GitHub.