### Start a Subscription Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Use the `start()` method to initiate a subscription immediately or at a specified future date. Fires a `SubscriptionStarted` event. ```php $subscriber->subscription->start(); // To start it immediately $subscriber->subscription->start($startDate); // To determine when to start ``` -------------------------------- ### Starting a Subscription Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Initiates a subscription immediately or schedules it for a future start date. Fires a `SubscriptionStarted` event. ```APIDOC ## Starting a Subscription ### Description Starts a subscription immediately or schedules it for a future start date. This method fills the `started_at` column. ### Method `start()` ### Parameters #### Path Parameters - `startDate` (DateTime|null) - Optional - The date when the subscription should start. If null, it starts immediately. ### Request Example ```php $subscriber->subscription->start(); // Starts immediately $subscriber->subscription->start($startDate); // Starts on a specific date ``` ### Response This method does not return a value but updates the subscription status and fires events. ``` -------------------------------- ### Install Laravel Soulbscription Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Install the package via Composer and run migrations to set up the necessary database tables. Optional commands allow publishing migrations and configuration files. ```bash composer require lucasdotvin/laravel-soulbscription # Optional: publish migrations and config php artisan vendor:publish --tag="soulbscription-migrations" php artisan vendor:publish --tag="soulbscription-config" php artisan migrate ``` -------------------------------- ### Define Subscription Start Date Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Schedule a subscription to start at a future date, useful for registrations that should take effect later. ```php validated()); $student->course()->associate($course); $student->save(); $plan = Plan::find($request->input('plan_id')); $student->subscribeTo($plan, startDate: $course->starts_at); return redirect()->route('admin.students.index'); } } ``` -------------------------------- ### Install Laravel Soulbscription Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Install the package using Composer. This command fetches and installs the latest version of the Soulbscription package into your Laravel project. ```bash composer require lucasdotvin/laravel-soulbscription ``` -------------------------------- ### Switch to a New Plan Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Change a user's current subscription plan. If no arguments are passed, it suppresses the current subscription and starts a new one immediately. This fires a SubscriptionStarted event. ```php $student->switchTo($newPlan); ``` -------------------------------- ### Listen to Soulbscription Events Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Handle lifecycle actions by listening to Laravel events fired by Soulbscription. Example listener demonstrates accessing the subscription and subscriber models from the event. ```php [SendWelcomeEmail::class], SubscriptionRenewed::class => [ChargeRenewalPayment::class], SubscriptionCanceled::class => [SendCancellationEmail::class], SubscriptionSuppressed::class => [RevokeAccessImmediately::class], SubscriptionScheduled::class => [NotifyUpcomingPlanChange::class], FeatureConsumed::class => [TrackUsageAnalytics::class], FeatureTicketCreated::class => [SendTicketConfirmation::class], ]; // Example listener — SubscriptionStarted carries the Subscription model class SendWelcomeEmail { public function handle(SubscriptionStarted $event): void { $subscription = $event->subscription; $subscriber = $subscription->subscriber; // the User (or other model) Mail::to($subscriber->email)->send(new WelcomeSubscriptionMail($subscription)); } } ``` -------------------------------- ### Subscribe User to a Plan Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Subscribes a user to a plan, automatically calculating expiration. Supports custom expiration and start dates. ```php first(); // Immediate subscription, expiration auto-calculated from plan periodicity $subscription = $user->subscribeTo($gold); // => fires SubscriptionStarted event // Custom expiration date $subscription = $user->subscribeTo($gold, expiration: today()->addYear()); // Deferred start date (e.g. subscription starts when a course begins) $subscription = $user->subscribeTo($gold, startDate: now()->addDays(14)); // => fires SubscriptionScheduled event (future start) echo $subscription->expired_at; // e.g. "2025-08-22" echo $subscription->started_at; // e.g. "2025-07-22" ``` -------------------------------- ### Create Ticket for Non-Consumable Feature Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Issue a ticket for a non-consumable feature, granting access for a specified period. This example demonstrates creating a ticket within a controller. ```php class UserFeatureTrialController extends Controller { public function store(FeatureTrialRequest $request, User $user) { $featureName = $request->input('feature_name'); $expiration = today()->addDays($request->input('trial_days')); $user->giveTicketFor($featureName, $expiration); return redirect()->route('admin.users.show', $user); } } ``` -------------------------------- ### $subscriber->subscribeTo() Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Subscribes a model (subscriber) to a specified plan. This method automatically calculates the expiration date based on the plan's periodicity and accepts optional custom expiration and start dates. ```APIDOC ## $subscriber->subscribeTo() ### Description Subscribes the model to a plan. Automatically calculates expiration from plan periodicity. Accepts optional custom expiration and start date. ### Method ```php $subscriber->subscribeTo(Plan $plan, ?DateTimeInterface $expiration = null, ?DateTimeInterface $startDate = null) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **plan** (Plan) - The plan to subscribe the model to. - **expiration** (DateTimeInterface, optional) - A custom expiration date for the subscription. - **startDate** (DateTimeInterface, optional) - A custom start date for the subscription. ### Request Example ```php first(); // Subscribe with auto-calculated expiration $subscription = $user->subscribeTo($gold); // Subscribe with a custom expiration date $subscription = $user->subscribeTo($gold, expiration: today()->addYear()); // Subscribe with a custom start date $subscription = $user->subscribeTo($gold, startDate: now()->addDays(14)); ``` ### Response #### Success Response (Subscription) Returns the created Subscription model. #### Response Example ```php { "expired_at": "2025-08-22", "started_at": "2025-07-22" } ``` ``` -------------------------------- ### Retrieve Last Subscription Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Get the user's last subscription, regardless of its status (active or expired). This is useful for operations like renewing an expired subscription. ```php $subscriber->lastSubscription(); ``` ```php $subscriber->lastSubscription()->renew(); ``` -------------------------------- ### Publish and Run Migrations Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Publish the package's migration files and then run the migrations to set up the necessary database tables for subscriptions and features. ```bash php artisan vendor:publish --tag="soulbscription-migrations" php artisan migrate ``` -------------------------------- ### Run Tests Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Execute the project's test suite using Composer. ```bash composer test ``` -------------------------------- ### Publish Configuration Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Publish the package configuration files using the `php artisan vendor:publish` command. ```bash php artisan vendor:publish --tag="soulbscription-config" ``` -------------------------------- ### Define Yearly Plan Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Create a yearly subscription plan. ```php // Yearly plan $enterprise = Plan::create([ 'name' => 'enterprise', 'periodicity_type' => PeriodicityType::Year, 'periodicity' => 1, ]); ``` -------------------------------- ### Define Monthly Plan with Grace Period Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Create a monthly subscription plan that includes a 7-day grace period before renewal. ```php 'gold', 'periodicity_type' => PeriodicityType::Month, 'periodicity' => 1, 'grace_days' => 7, ]); ``` -------------------------------- ### Configure Soulbscription Package Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Customize model bindings, enable feature tickets, and control migration autoloading in the `config/soulbscription.php` file. Feature tickets can also be controlled via environment variables. ```php [ // Set to true to prevent the package from autoloading its migrations 'cancel_migrations_autoloading' => false, ], // Enable feature tickets system (default: false) // Can also be set via SOULBSCRIPTION_FEATURE_TICKETS env variable 'feature_tickets' => env('SOULBSCRIPTION_FEATURE_TICKETS', false), 'models' => [ // Swap any model with your own custom extension 'feature' => \LucasDotVin\Soulbscription\Models\Feature::class, 'feature_consumption' => \LucasDotVin\Soulbscription\Models\FeatureConsumption::class, 'feature_ticket' => \LucasDotVin\Soulbscription\Models\FeatureTicket::class, 'feature_plan' => \LucasDotVin\Soulbscription\Models\FeaturePlan::class, 'plan' => \LucasDotVin\Soulbscription\Models\Plan::class, 'subscription' => \LucasDotVin\Soulbscription\Models\Subscription::class, 'subscription_renewal' => \LucasDotVin\Soulbscription\Models\SubscriptionRenewal::class, 'subscriber' => [ // Set to true if your subscriber model uses UUIDs as primary keys 'uses_uuid' => env('SOULBSCRIPTION_SUBSCRIBER_USES_UUID', false), ], ], ]; ``` -------------------------------- ### Create Monthly Plans Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Define subscription plans with a name, periodicity type (e.g., Month), and periodicity interval. These plans are recurring on a monthly basis. ```php 'silver', 'periodicity_type' => PeriodicityType::Month, 'periodicity' => 1, ]); $gold = Plan::create([ 'name' => 'gold', 'periodicity_type' => PeriodicityType::Month, 'periodicity' => 1, ]); } } ``` -------------------------------- ### Publish Upgrade Migrations Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md When upgrading to a new major version, publish the specific upgrade migration files and run them to update your database schema. ```bash php artisan vendor:publish --tag="soulbscription-migrations-upgrades-1.x-2.x" php artisan migrate ``` -------------------------------- ### Define Free/Permanent Plan Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Create a plan with no expiration, suitable for free or permanent access tiers. ```php // Free / permanent plan (no expiration) $free = Plan::create([ 'name' => 'free', 'periodicity_type' => null, 'periodicity' => null, ]); ``` -------------------------------- ### Subscribe User to a Plan Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Implement a listener to automatically subscribe a user to a plan when an event, such as 'PaymentApproved', occurs. The `subscribeTo` method handles expiration calculation by default. ```php user; $plan = $event->plan; $subscriber->subscribeTo($plan); } } ``` -------------------------------- ### $subscriber->switchTo() Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Switches the subscriber to a new plan. This can be done immediately, which suppresses the current subscription, or scheduled for the end of the current billing period. Custom expiration dates for the new plan are also supported. ```APIDOC ## $subscriber->switchTo() ### Description Switches the subscriber to a new plan, either immediately (suppresses the current subscription) or at the end of the current billing period. Supports custom expiration dates for the new plan. ### Method ```php $subscriber->switchTo(Plan $plan, bool $immediately = true, ?DateTimeInterface $expiration = null) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **plan** (Plan) - The new plan to switch to. - **immediately** (bool, optional) - If true, the switch happens immediately, suppressing the current subscription. Defaults to true. - **expiration** (DateTimeInterface, optional) - A custom expiration date for the new subscription. ### Request Example ```php first(); // Switch immediately $newSubscription = $user->switchTo($enterprise); // Schedule switch for the end of the current billing period $user->switchTo($enterprise, immediately: false); // Switch with a custom expiration date for the new plan $user->switchTo($enterprise, expiration: today()->addMonths(6)); ``` ### Response #### Success Response (Subscription) Returns the new Subscription model. #### Response Example None provided in source. ``` -------------------------------- ### Create Permanent Plan Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Define a plan that users can subscribe to permanently by setting both `periodicity_type` and `periodicity` attributes to null. This is suitable for 'free' or one-time plans. ```php $free = Plan::create([ 'name' => 'free', 'periodicity_type' => null, 'periodicity' => null, ]); ``` -------------------------------- ### Schedule a Plan Switch Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Schedule a user to switch to a new plan upon their current subscription's expiration, without immediate effect. This is useful for avoiding partial refunds and billing only upon expiration. This fires a SubscriptionScheduled event. ```php $primeMonthly = Plan::whereName('prime-monthly')->first(); $user->subscribeTo($primeMonthly); ... $primeYearly = Plan::whereName('prime-yearly')->first(); $user->switchTo($primeYearly, immediately: false); ``` -------------------------------- ### Create Plan with Grace Days Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Configure a plan to include grace days after expiration. Subscribers will retain access to features during this period before their access is suspended. ```php $gold = Plan::create([ 'name' => 'gold', 'periodicity_type' => PeriodicityType::Month, 'periodicity' => 1, 'grace_days' => 7, ]); ``` -------------------------------- ### Check Feature Availability Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Verify if a feature can be consumed using `canConsume` (checks access and charges) or `cantConsume` (reverses `canConsume`). ```php $subscriber->canConsume('deploy-minutes', 10); ``` ```php $subscriber->cantConsume('deploy-minutes', 10); ``` -------------------------------- ### Create a Feature Ticket Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Grant a feature ticket to a subscriber using `giveTicketFor`. Specify the feature name, expiration date, and optionally the number of charges. ```php $subscriber->giveTicketFor('deploy-minutes', today()->addMonth(), 10); ``` -------------------------------- ### Switch User to a New Plan Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Switches a user to a new plan, either immediately or at the end of the current billing period. Supports custom expiration for the new plan. ```php first(); // Immediate switch — current subscription suppressed now, new one starts today $newSubscription = $user->switchTo($enterprise); // => fires SubscriptionSuppressed (old) + SubscriptionStarted (new) // Scheduled switch — user keeps current plan until it expires, then moves to new plan $user->switchTo($enterprise, immediately: false); // => fires SubscriptionScheduled event for the future subscription // Switch with a custom expiration on the new plan $user->switchTo($enterprise, expiration: today()->addMonths(6)); ``` -------------------------------- ### Cancel Subscription Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Mark a subscription as canceled by setting the 'canceled_at' timestamp. Access is not revoked immediately to avoid handling refunds. This fires a SubscriptionCanceled event. ```php $subscriber->subscription->cancel(); ``` -------------------------------- ### Check Subscription Status and Access Data Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Use built-in scopes, accessors, and relationship helpers to query and inspect subscription state. Access active subscription details and check if a subscription is overdue. ```php first(); // Check current plan subscription $user->hasSubscriptionTo($gold); // bool $user->isSubscribedTo($gold); // bool (alias) $user->missingSubscriptionTo($gold); // bool $user->isNotSubscribedTo($gold); // bool (alias) // Access the active subscription $sub = $user->subscription; echo $sub->expired_at; echo $sub->started_at; echo $sub->canceled_at; echo $sub->suppressed_at; // Check if overdue (expired past grace days) if ($sub->isOverdue) { $sub->renew(); } // Retrieve last subscription regardless of status (including expired) $lastSub = $user->lastSubscription(); // Query subscriptions directly Subscription::canceled()->get(); Subscription::notCanceled()->get(); Subscription::notActive()->get(); // Access all renewals for a subscriber $user->renewals; ``` -------------------------------- ### Associate Features with Plans Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Link features to plans, specifying the number of charges for consumable features. This defines the limits or allowances for each plan. ```php use LucasDotVin\Soulbscription\Models\Feature; // ... $deployMinutes = Feature::whereName('deploy-minutes')->first(); $subdomains = Feature::whereName('subdomains')->first(); $silver->features()->attach($deployMinutes, ['charges' => 15]); $gold->features()->attach($deployMinutes, ['charges' => 25]); $gold->features()->attach($subdomains); ``` -------------------------------- ### $subscription->cancel() Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Marks a subscription as canceled by setting the `canceled_at` timestamp. This action does not immediately revoke access; the user retains access until the subscription's natural expiration date. ```APIDOC ## $subscription->cancel() ### Description Marks the subscription as canceled (sets `canceled_at`) without immediately revoking access. The user retains access until the subscription's natural expiration. ### Method ```php $subscription->cancel() ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php subscription->cancel(); ``` ### Response #### Success Response (void) This method does not return a value directly but updates the subscription record with a `canceled_at` timestamp. #### Response Example ```php // The canceled_at timestamp will be set echo $user->subscription->canceled_at; // current timestamp ``` ``` -------------------------------- ### $subscriber->giveTicketFor() Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Grants extra charges (or temporary access) for a feature via a ticket. Requires `feature_tickets` to be enabled in config. Tickets can expire or be permanent (`null` expiration). ```APIDOC ## $subscriber->giveTicketFor() — Grant a Feature Ticket Grants extra charges (or temporary access) for a feature via a ticket. Requires `feature_tickets` to be enabled in config. Tickets can expire or be permanent (`null` expiration). ```php giveTicketFor('api-calls', today()->addMonth(), 500); // => fires FeatureTicketCreated event // Grant temporary access to a non-consumable feature (trial) $user->giveTicketFor('custom-domain', today()->addDays(14)); // Grant permanent (non-expiring) bonus charges $user->giveTicketFor('api-calls', null, 1000); echo $ticket->charges; // 500 echo $ticket->expired_at; // 30 days from now ``` ``` -------------------------------- ### Define Postpaid Feature Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Create a postpaid consumable feature that allows charges to go negative, intended for retroactive billing of usage like CPU time. ```php // Postpaid feature — can exceed charges, billed retroactively $cpuUsage = Feature::create([ 'consumable' => true, 'postpaid' => true, 'name' => 'cpu-usage', ]); ``` -------------------------------- ### Consume a Feature Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Register feature consumption using the `consume` method. Pass the feature name and amount. Throws `OutOfBoundsException` or `OverflowException` if unavailable or insufficient. ```php $subscriber->consume('deploy-minutes', 4.5); ``` -------------------------------- ### Define Postpaid Feature Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Set a feature as 'postpaid' to allow usage even when charges are insufficient, enabling later billing or usage tracking. ```php $cpuUsage = Feature::create([ 'consumable' => true, 'postpaid' => true, 'name' => 'cpu-usage', ]); ``` -------------------------------- ### Plan::features()->attach() Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Associates features with a plan through a many-to-many pivot table. Consumable features require a 'charges' value, while non-consumable features do not. ```APIDOC ## Plan::features()->attach() ### Description Attaches features to a plan via a many-to-many pivot. Consumable features require a `charges` value on the pivot; non-consumable features do not. ### Method ```php Plan::features()->attach(Feature $feature, array $attributes = []) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **feature** (Feature) - The feature model to attach. - **attributes** (array) - An associative array of attributes to attach to the pivot record. For consumable features, this should include a `charges` key. ### Request Example ```php first(); $apiCalls = Feature::whereName('api-calls')->first(); // Attach a consumable feature with charges $silver->features()->attach($apiCalls, ['charges' => 100]); // Attach a non-consumable feature without charges $nonConsumableFeature = Feature::whereName('custom-domain')->first(); $silver->features()->attach($nonConsumableFeature); ``` ### Response #### Success Response (void) This method does not return a value directly, but modifies the database. #### Response Example None ``` -------------------------------- ### Check Remaining Charges for Features Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Retrieves the remaining charges for a consumable feature. `balance()` can return negative values for postpaid features, while `getRemainingCharges()` floors the result at 0. ```php balance('api-calls'); // e.g. 750 (out of 1000 allocated, 250 consumed) $safeRemaining = $user->getRemainingCharges('api-calls'); // Always >= 0, even for postpaid features with negative balance $currentUsage = $user->getCurrentConsumption('api-calls'); // e.g. 250 $totalAllocated = $user->getTotalCharges('api-calls'); // e.g. 1000 (from plan) + any ticket charges ``` -------------------------------- ### Define Consumable Feature with Daily Periodicity Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Create a consumable feature that renews daily, suitable for tracking usage like API calls per day. ```php true, 'name' => 'api-calls', 'periodicity_type' => PeriodicityType::Day, 'periodicity' => 1, ]); ``` -------------------------------- ### Cancel a Subscription Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Marks a subscription as canceled by setting the `canceled_at` timestamp. Access is retained until the natural expiration date. ```php subscription->cancel(); // => fires SubscriptionCanceled event // Access remains until $user->subscription->expired_at echo $user->subscription->canceled_at; // current timestamp ``` -------------------------------- ### Attach Features to a Plan Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Associates features with a plan using the many-to-many pivot table. Consumable features require a 'charges' value. ```php first(); $gold = Plan::whereName('gold')->first(); $apiCalls = Feature::whereName('api-calls')->first(); $customDomain = Feature::whereName('custom-domain')->first(); $storage = Feature::whereName('storage')->first(); // Silver: 100 API calls/day, 5 GB storage $silver->features()->attach($apiCalls, ['charges' => 100]); $silver->features()->attach($storage, ['charges' => 5368709120]); // 5 GB in bytes // Gold: 1000 API calls/day, 50 GB storage, custom domain access $gold->features()->attach($apiCalls, ['charges' => 1000]); $gold->features()->attach($storage, ['charges' => 53687091200]); // 50 GB in bytes $gold->features()->attach($customDomain); // no charges needed for non-consumable ``` -------------------------------- ### Create Quota Feature Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Define a feature as a quota that has an unique, unexpirable consumption. Use this for features that reflect a constant value, like system storage. ```php class FeatureSeeder extends Seeder { public function run() { $storage = Feature::create([ 'consumable' => true, 'quota' => true, 'name' => 'storage', ]); } } ``` -------------------------------- ### $subscriber->consume() Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Records consumption of a consumable feature. Throws OutOfBoundsException if the feature is not available on the user's plan, and OverflowException if charges are exhausted (unless the feature is postpaid). ```APIDOC ## $subscriber->consume() — Consume a Feature Records consumption of a consumable feature. Throws `OutOfBoundsException` if the feature is not available on the user's plan, and `OverflowException` if charges are exhausted (unless the feature is postpaid). ```php consume('api-calls', 10); // => fires FeatureConsumed event // Consume a non-consumable feature (no amount needed) $user->consume('custom-domain'); } catch (OutOfBoundsException $e) { // Feature not available in the user's current plan return response()->json(['error' => 'Feature not available.'], 403); } catch (OverflowException $e) { // Not enough remaining charges return response()->json(['error' => 'Feature limit reached.'], 429); } ``` ``` -------------------------------- ### Define Quota Feature Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Create a quota-based consumable feature for tracking a persistent single-value consumption, such as storage space. ```php // Quota feature — persistent single-value consumption (e.g. storage) $storage = Feature::create([ 'consumable' => true, 'quota' => true, 'name' => 'storage', ]); ``` -------------------------------- ### $subscriber->balance() / getRemainingCharges() Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Returns the remaining charges for a consumable feature. `balance()` may return negative values for postpaid features; `getRemainingCharges()` floors the result at 0. ```APIDOC ## $subscriber->balance() / getRemainingCharges() — Check Remaining Charges Returns the remaining charges for a consumable feature. `balance()` may return negative values for postpaid features; `getRemainingCharges()` floors the result at 0. ```php balance('api-calls'); // e.g. 750 (out of 1000 allocated, 250 consumed) $safeRemaining = $user->getRemainingCharges('api-calls'); // Always >= 0, even for postpaid features with negative balance $currentUsage = $user->getCurrentConsumption('api-calls'); // e.g. 250 $totalAllocated = $user->getTotalCharges('api-calls'); // e.g. 1000 (from plan) + any ticket charges ``` ``` -------------------------------- ### Consume a Feature with Error Handling Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Records consumption of a consumable feature. Throws OutOfBoundsException if the feature is not available on the user's plan, and OverflowException if charges are exhausted (unless the feature is postpaid). ```php consume('api-calls', 10); // => fires FeatureConsumed event // Consume a non-consumable feature (no amount needed) $user->consume('custom-domain'); } catch (OutOfBoundsException $e) { // Feature not available in the user's current plan return response()->json(['error' => 'Feature not available.'], 403); } catch (OverflowException $e) { // Not enough remaining charges return response()->json(['error' => 'Feature limit reached.'], 429); } ``` -------------------------------- ### $subscriber->canConsume() / cantConsume() Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Checks whether a subscriber can consume a given amount of a feature. Returns `true` for non-consumable features (access check only) and `true` for postpaid features regardless of balance. ```APIDOC ## $subscriber->canConsume() / cantConsume() — Check Consumability Checks whether a subscriber can consume a given amount of a feature. Returns `true` for non-consumable features (access check only) and `true` for postpaid features regardless of balance. ```php canConsume('api-calls', 50)) { $user->consume('api-calls', 50); } else { return response()->json(['error' => 'Insufficient API call quota.'], 429); } // Inverse check if ($user->cantConsume('storage', 1073741824)) { // 1 GB return response()->json(['error' => 'Not enough storage quota.'], 429); } // Boolean access check (ignores charges) if ($user->hasFeature('custom-domain')) { // allow custom domain setup } if ($user->missingFeature('custom-domain')) { return response()->json(['error' => 'Upgrade to access custom domains.'], 403); } ``` ``` -------------------------------- ### Create Non-Expirable Feature Ticket Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Create a ticket that never expires by passing `null` for the expiration date. Remember to manage these tickets manually upon subscription cancellation. ```php $subscriber->giveTicketFor('deploy-minutes', null, 10); ``` -------------------------------- ### Set Consumed Quota in Controller Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md In a controller, store a file, calculate its size, and then set the consumed quota for a specific feature. Ensure the feature is defined as a quota feature in your seeder. ```php class PhotoController extends Controller { public function store(Request $request) { $userFolder = auth()->id() . '-files'; $request->file->store($userFolder); $usedSpace = collect(Storage::allFiles($userFolder)) ->map(fn (string $subFile) => Storage::size($subFile)) ->sum(); auth()->user()->setConsumedQuota('storage', $usedSpace); return redirect()->route('files.index'); } } ``` -------------------------------- ### Immediately Revoke a Subscription Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Immediately revokes all feature access by setting the `suppressed_at` timestamp on the subscription. ```php subscription->suppress(); // => fires SubscriptionSuppressed event // Access revoked immediately echo $user->subscription->suppressed_at; // current timestamp ``` -------------------------------- ### Define Consumable and Renewable Feature Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Create features by defining their properties. 'consumable' set to true allows for limited usage, and 'periodicity_type'/'periodicity' handle renewal. ```php true, 'name' => 'deploy-minutes', 'periodicity_type' => PeriodicityType::Day, 'periodicity' => 1, ]); $customDomain = Feature::create([ 'consumable' => false, 'name' => 'custom-domain', ]); } } ``` -------------------------------- ### Grant Feature Ticket for Extra Charges Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Grants extra charges or temporary access for a feature via a ticket, requiring `feature_tickets` to be enabled in configuration. Tickets can be permanent or expire. ```php giveTicketFor('api-calls', today()->addMonth(), 500); // => fires FeatureTicketCreated event // Grant temporary access to a non-consumable feature (trial) $user->giveTicketFor('custom-domain', today()->addDays(14)); // Grant permanent (non-expiring) bonus charges $user->giveTicketFor('api-calls', null, 1000); echo $ticket->charges; // 500 echo $ticket->expired_at; // 30 days from now ``` -------------------------------- ### Suppress Subscription Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Immediately revoke a subscription by setting the 'suppressed_at' timestamp. This differs from 'cancel' as it revokes access immediately. This fires a SubscriptionSuppressed event. ```php $subscriber->subscription->suppress(); ``` -------------------------------- ### $subscription->renew() Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Renews an existing subscription, extending its expiration date based on the associated plan's periodicity. This method handles both active and overdue subscriptions and creates a renewal record. It also supports setting a specific expiration date for the renewal. ```APIDOC ## $subscription->renew() ### Description Extends the subscription's expiration date based on the plan's periodicity. Creates a renewal record. Handles both current and overdue subscriptions. ### Method ```php $subscription->renew(?DateTimeInterface $expirationDate = null) ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **expirationDate** (DateTimeInterface, optional) - A specific date to set as the new expiration date. If not provided, the expiration is calculated based on the plan's periodicity. ### Request Example ```php subscription->renew(); // Renew an expired subscription retrieved via lastSubscription() $user->lastSubscription()->renew(); // Renew with a specific expiration date $user->subscription->renew(expirationDate: today()->addMonths(3)); ``` ### Response #### Success Response (void) This method does not return a value directly but updates the subscription's expiration date and creates a renewal record. #### Response Example ```php // After renewal, the expired_at timestamp will be updated echo $user->fresh()->subscription->expired_at; ``` ``` -------------------------------- ### Checking Feature Availability Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Provides methods to check if a subscriber can consume a feature, has access to a feature, or is missing a feature. ```APIDOC ## Checking Feature Availability ### Description These methods allow you to check the availability and access rights of features for a subscriber. ### Methods #### `canConsume(string $featureName, float $amount)` Checks if a subscriber can consume a specific amount of a given feature. Returns `true` if the feature is available and charges are sufficient, `false` otherwise. ```php $subscriber->canConsume('deploy-minutes', 10); ``` #### `cantConsume(string $featureName, float $amount)` Checks if a subscriber cannot consume a specific amount of a given feature. This is the inverse of `canConsume()`. ```php $subscriber->cantConsume('deploy-minutes', 10); ``` #### `hasFeature(string $featureName)` Checks if a subscriber has access to a given feature, regardless of charges. ```php $subscriber->hasFeature('deploy-minutes'); ``` #### `missingFeature(string $featureName)` Checks if a subscriber does not have access to a given feature. This is the inverse of `hasFeature()`. ```php $subscriber->missingFeature('deploy-minutes'); ``` ``` -------------------------------- ### Apply HasSubscriptions Trait to User Model Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Use the `HasSubscriptions` trait in your Eloquent model to gain access to all subscription and feature consumption methods. ```php hasFeature('deploy-minutes'); ``` ```php $subscriber->missingFeature('deploy-minutes'); ``` -------------------------------- ### Consuming a Feature Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Registers the consumption of a given feature by a subscriber. Throws exceptions for unavailable features or insufficient charges. Fires a `FeatureConsumed` event. ```APIDOC ## Consuming a Feature ### Description Registers the consumption of a specified amount of a feature. This method checks for feature availability and sufficient charges, throwing `OutOfBoundsException` or `OverflowException` if necessary. It also fires a `FeatureConsumed` event. ### Method `consume(string $featureName, float $amount) ### Parameters #### Path Parameters - `featureName` (string) - Required - The name of the feature to consume. - `amount` (float) - Required - The amount of the feature to consume. ### Request Example ```php $subscriber->consume('deploy-minutes', 4.5); ``` ### Response This method does not return a value but updates the feature consumption and fires events. It may throw `OutOfBoundsException` or `OverflowException`. ``` -------------------------------- ### Fetch Current Balance of a Consumable Feature Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Retrieve the remaining charges or limit for a specific consumable feature, like 'notes-download'. This is an alias for getRemainingCharges. ```php $student->balance('notes-download'); ``` -------------------------------- ### Add HasSubscriptions Trait to User Model Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md To enable subscription management, add the HasSubscriptions trait to your User model or any other entity that will manage subscriptions. ```php suppress() Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Immediately revokes all feature access associated with a subscription by setting the `suppressed_at` timestamp. This action takes effect immediately. ```APIDOC ## $subscription->suppress() ### Description Immediately suppresses the subscription by setting `suppressed_at`, revoking all feature access right away. ### Method ```php $subscription->suppress() ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```php subscription->suppress(); ``` ### Response #### Success Response (void) This method does not return a value directly but updates the subscription record with a `suppressed_at` timestamp. #### Response Example ```php // The suppressed_at timestamp will be set echo $user->subscription->suppressed_at; // current timestamp ``` ``` -------------------------------- ### Check Feature Consumability Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Checks if a subscriber can consume a feature, returning true for non-consumable or postpaid features. Also includes inverse checks and direct feature access checks. ```php canConsume('api-calls', 50)) { $user->consume('api-calls', 50); } else { return response()->json(['error' => 'Insufficient API call quota.'], 429); } // Inverse check if ($user->cantConsume('storage', 1073741824)) { // 1 GB return response()->json(['error' => 'Not enough storage quota.'], 429); } // Boolean access check (ignores charges) if ($user->hasFeature('custom-domain')) { // allow custom domain setup } if ($user->missingFeature('custom-domain')) { return response()->json(['error' => 'Upgrade to access custom domains.'], 403); } ``` -------------------------------- ### Override Subscription Expiration Date Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Set a specific expiration date for a subscription, such as one year from today. ```php $subscriber->subscribeTo($plan, expiration: today()->addYear()); ``` -------------------------------- ### Creating Feature Tickets Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Allows subscribers to acquire charges for a feature through tickets. Tickets can be used for consumable or non-consumable features and can have expiration dates or be non-expirable. Fires a `FeatureTicketCreated` event. ```APIDOC ## Creating Feature Tickets ### Description Grants subscribers additional charges or access to features via tickets. Tickets can be for consumable or non-consumable features, with or without expiration dates. This method fires a `FeatureTicketCreated` event. ### Method `giveTicketFor(string $featureName, DateTime|null $expiration, float|null $charges = null)` ### Parameters #### Path Parameters - `featureName` (string) - Required - The name of the feature for which the ticket is created. - `expiration` (DateTime|null) - Optional - The expiration date of the ticket. If null, the ticket does not expire. - `charges` (float|null) - Optional - The number of charges the ticket provides. Ignored for non-consumable features. ### Request Example ```php // For a consumable feature with expiration and charges $subscriber->giveTicketFor('deploy-minutes', today()->addMonth(), 10); // For a non-consumable feature with expiration $user->giveTicketFor('feature-access', today()->addDays(7)); // For a consumable feature that never expires $subscriber->giveTicketFor('deploy-minutes', null, 10); ``` ### Response This method does not return a value but creates a feature ticket and fires events. Remember to manage non-expirable tickets appropriately (e.g., remove them upon subscription cancellation). ``` -------------------------------- ### Renew Subscription Source: https://github.com/lucasdotvin/laravel-soulbscription/blob/main/README.md Renew the current subscription. This method calculates a new expiration date based on the current date and fires a SubscriptionRenewed event. ```php $subscriber->subscription->renew(); ``` -------------------------------- ### Renew a Subscription Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Extends a subscription's expiration date based on the plan's periodicity. Handles both current and overdue subscriptions and allows specifying a custom expiration date. ```php subscription->renew(); // => fires SubscriptionRenewed event // Renew an expired subscription retrieved via lastSubscription() $user->lastSubscription()->renew(); // Renew with a specific expiration $user->subscription->renew(expirationDate: today()->addMonths(3)); echo $user->fresh()->subscription->expired_at; // updated expiration date ``` -------------------------------- ### Define Non-Consumable Feature Source: https://context7.com/lucasdotvin/laravel-soulbscription/llms.txt Create a non-consumable feature, typically used as a boolean access flag for features like custom domain support. ```php // Non-consumable feature — access flag only (e.g. custom domain) $customDomain = Feature::create([ 'consumable' => false, 'name' => 'custom-domain', ]); ```