### Install License Server Package Source: https://context7.com/laravel-ready/license-server/llms.txt Installs the License Server package via Composer, publishes and runs migrations, and publishes configuration files. ```bash composer require laravel-ready/license-server php artisan vendor:publish --tag=license-server-migrations php artisan migrate --path=/database/migrations/laravel-ready/license-server php artisan vendor:publish --tag=license-server-configs ``` -------------------------------- ### License Server Configuration Example Source: https://context7.com/laravel-ready/license-server/llms.txt Shows the default configuration options for the License Server package, including table prefix, subdomain allowance, expiration periods, and API middleware. ```php 'ls', // Allow subdomain licensing (default: true) 'allow_subdomains' => true, // Default license expiration in days (default: 365) 'license_expiration_days' => 365, // Allow lifetime licenses (default: true) 'allow_lifetime_licenses' => true, // Allow trial licenses (default: true) 'allow_trial_licenses' => true, // Trial license expiration in days (default: 30) 'trial_expiration_days' => 30, // Admin API middleware 'admin_api_middleware' => [ 'auth:sanctum', 'throttle:api', ], // Event listeners 'event_listeners' => [ 'license_checked' => null, // App\Listeners\LicenseCheckedListener::class ], // Custom controllers 'controllers' => [ 'license_validation' => [ LaravelReady\LicenseServer\Http\Controllers\Api\LicenseValidationController::class, 'licenseValidate' ] ], // Additional middlewares for license validation routes 'license_middlewares' => [] ]; ``` -------------------------------- ### Install Laravel License Server via Composer Source: https://github.com/laravel-ready/license-server/blob/main/README.md Installs the license-server package using Composer. This is the first step for integrating the license management system into your Laravel application. ```bash composer require laravel-ready/license-server ``` -------------------------------- ### Get License Information by Key, User ID, or Domain Source: https://github.com/laravel-ready/license-server/blob/main/README.md Retrieve license details using different identifiers. These methods allow fetching license data based on a unique license key, a user ID (optionally with a license key), or a domain (optionally with a license key). ```php LicenseService::getLicenseByKey(string $licenseKey) LicenseService::getLicenseByUserId(int $userId, string $licenseKey = null) LicenseService::getLicenseByDomain(string $domain, string $licenseKey = null) ``` -------------------------------- ### Get License Information Source: https://github.com/laravel-ready/license-server/blob/main/README.md Retrieve license details based on different criteria. You can get a license by its unique key, by a user ID (optionally with a license key), or by a domain name (optionally with a license key). ```APIDOC ## GET /api/license-server/licenses ### Description Retrieves license information based on provided parameters. ### Method GET ### Endpoint /api/license-server/licenses ### Parameters #### Query Parameters - **licenseKey** (string) - Optional - The unique key of the license. - **userId** (integer) - Optional - The ID of the user associated with the license. - **domain** (string) - Optional - The domain associated with the license. ### Request Example ```json { "example": "GET /api/license-server/licenses?licenseKey=46fad906-bc51-435f-9929-db46cb4baf13" } ``` ```json { "example": "GET /api/license-server/licenses?userId=1&licenseKey=46fad906-bc51-435f-9929-db46cb4baf13" } ``` ```json { "example": "GET /api/license-server/licenses?domain=example.com&licenseKey=46fad906-bc51-435f-9929-db46cb4baf13" } ``` ### Response #### Success Response (200) - **domain** (string) - The domain associated with the license. - **license_key** (string) - The unique key of the license. - **status** (string) - The current status of the license (e.g., 'active', 'inactive'). - **expiration_date** (string) - The expiration date of the license. - **is_trial** (boolean) - Indicates if the license is a trial license. - **is_lifetime** (boolean) - Indicates if the license is a lifetime license. #### Response Example ```json { "example": { "domain": "example.com", "license_key": "46fad906-bc51-435f-9929-db46cb4baf13", "status": "active", "expiration_date": "2024-12-31T23:59:59.000000Z", "is_trial": false, "is_lifetime": true } } ``` ``` -------------------------------- ### Add License to Domain or User using LicenseService Source: https://github.com/laravel-ready/license-server/blob/main/README.md Demonstrates how to add licenses using the LicenseService. Licenses can be associated with a domain, a user, or both. Optional parameters allow for setting expiration, lifetime, or trial periods. ```php // get licensable product $product = Product::find(1); $user = User::find(1); // add license to domain $license = LicenseService::addLicense($product, 'example.com', $user->id); // add license to user $license = LicenseService::addLicense($product, null, $user->id); // with expiration in days (see configs for defaults) $license = LicenseService::addLicense($product, null, $user->id, 999); // with lifetime license (see configs for defaults) $license = LicenseService::addLicense($product, null, $user->id, null, true); // with trial license (see configs for defaults) $license = LicenseService::addLicense($product, null, $user->id, null, false, true); ``` -------------------------------- ### Publish and Migrate License Server Database Source: https://github.com/laravel-ready/license-server/blob/main/README.md Publishes the migration files for the license server and then applies them to the database. This sets up the necessary database tables for license management. ```bash php artisan vendor:publish --tag=license-server-migrations php artisan migrate --path=/database/migrations/laravel-ready/license-server ``` -------------------------------- ### Listen to LicenseChecked Event in PHP Source: https://context7.com/laravel-ready/license-server/llms.txt Create a listener to perform custom actions when a license is checked. This involves defining a listener class and registering it in the configuration file. It allows for actions like updating usage statistics or sending notifications. ```php license; // Access any custom data sent from the client $data = $event->data; // Log license check \Log::info("License checked", [ 'license_key' => $license->license_key, 'domain' => $license->domain, 'status' => $license->status, 'custom_data' => $data ]); // Perform custom logic // - Update usage statistics // - Send notifications // - Rate limiting } } // Register in config/license-server.php 'event_listeners' => [ 'license_checked' => App\Listeners\LicenseCheckedListener::class, ], ``` -------------------------------- ### POST /api/license-server/auth/login Source: https://context7.com/laravel-ready/license-server/llms.txt Authenticates a client application using a license key and domain. Returns a Sanctum access token for subsequent API calls. The `x-host` and `x-host-name` headers are required. ```APIDOC ## POST /api/license-server/auth/login ### Description Client applications authenticate using the license key and domain. Returns a Sanctum access token for subsequent API calls. ### Method POST ### Endpoint `/api/license-server/auth/login` ### Parameters #### Path Parameters *None* #### Query Parameters *None* #### Request Body - **license_key** (string) - Required - The license key for authentication. ### Request Example ```bash curl -X POST "https://your-server.com/api/license-server/auth/login" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "x-host: example.com" \ -H "x-host-name: example.com" \ -d '{ "license_key": "46fad906-bc51-435f-9929-db46cb4baf13" }' ``` ### Response #### Success Response (200) - **status** (boolean) - Indicates if the login was successful. - **message** (string) - A message confirming the login. - **access_token** (string) - The Sanctum access token for authenticated requests. #### Response Example ```json { "status": true, "message": "Successfully logged in.", "access_token": "abc123def456..." } ``` #### Error Response (401) - **status** (boolean) - Indicates failure. - **message** (string) - Error message (e.g., "Invalid license key or lincese source.", "This IP address is not allowed. Please contact the license provider."). #### Error Response Example ```json { "status": false, "message": "Invalid license key or lincese source." } ``` ### Notes - `x-host` and `x-host-name` headers are required (DomainGuardMiddleware). ``` -------------------------------- ### Retrieve License by Key with LicenseService::getLicenseByKey() Source: https://context7.com/laravel-ready/license-server/llms.txt Retrieves a license using its unique UUID license key. This method returns null if the provided key is not a valid UUID format or if no matching license is found in the system. ```php domain; echo "Status: " . $license->status; echo "Expires in: " . $license->expires_in . " days"; } else { echo "License not found"; } // Invalid UUID returns null $invalid = LicenseService::getLicenseByKey("not-a-uuid"); // null ``` -------------------------------- ### Publish License Server Configuration Source: https://github.com/laravel-ready/license-server/blob/main/README.md Publishes the configuration files for the license server package. It is crucial to review and configure these settings according to your specific needs. ```bash php artisan vendor:publish --tag=license-server-configs ``` -------------------------------- ### Create LicenseChecked Event Listener Source: https://github.com/laravel-ready/license-server/blob/main/README.md Generate a listener for the `LicenseChecked` event to perform actions when a license is checked. This allows for custom logic execution, such as handling custom data passed during the license check. ```bash php artisan make:listener LicenseCheckedListener --event=LicenseChecked ``` -------------------------------- ### Retrieve License by Domain with LicenseService::getLicenseByDomain() Source: https://context7.com/laravel-ready/license-server/llms.txt Retrieves a license based on a provided domain name. The domain is automatically validated and normalized before the lookup. Subdomain handling is configurable. ```php id); // Returns: License model with UUID license_key // Create a user-based license (no domain) $license = LicenseService::addLicense($product, null, $user->id); // Create a license with custom expiration (999 days) $license = LicenseService::addLicense($product, null, $user->id, 999); // Create a lifetime license (never expires) $license = LicenseService::addLicense($product, null, $user->id, null, true); // Create a trial license (uses trial_expiration_days config, default 30) $license = LicenseService::addLicense($product, null, $user->id, null, false, true); // Error handling try { $license = LicenseService::addLicense($product, 'existing-domain.com', $user->id); } catch (LicenseException $e) { // "License already exists for this domain." // "Given model is not licensable." // "Domain or user id must be provided." // "Failed to create license with product model." } // License model properties echo $license->license_key; // "46fad906-bc51-435f-9929-db46cb4baf13" echo $license->domain; // "example.com" echo $license->status; // "active", "inactive", "suspended", "expired" echo $license->expiration_date; // Carbon datetime echo $license->is_trial; // boolean echo $license->is_lifetime; // boolean echo $license->expires_in; // Days until expiration (computed) ``` -------------------------------- ### POST /api/license-server/license Source: https://context7.com/laravel-ready/license-server/llms.txt Validates an authenticated license and returns license details. Requires authentication with a valid access token obtained from the login endpoint. The `x-host` and `x-host-name` headers are also required. ```APIDOC ## POST /api/license-server/license ### Description Validates an authenticated license and returns license details. Requires authentication with the access token from login. ### Method POST ### Endpoint `/api/license-server/license` ### Parameters #### Path Parameters *None* #### Query Parameters *None* #### Request Body - **custom_data** (string) - Optional - Any additional data for event listeners. ### Request Example ```bash curl -X POST "https://your-server.com/api/license-server/license" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "x-host: example.com" \ -H "x-host-name: example.com" \ -d '{ "custom_data": "any additional data for event listeners" }' ``` ### Response #### Success Response - **domain** (string) - The domain the license is associated with. - **license_key** (string) - The license key. - **status** (string) - The current status of the license (e.g., 'active'). - **expiration_date** (string) - The expiration date of the license in ISO 8601 format. - **is_trial** (boolean) - Indicates if the license is a trial. - **is_lifetime** (boolean) - Indicates if the license is a lifetime license. - **deleted_at** (string|null) - Timestamp of deletion if applicable. - **created_at** (string) - Timestamp of creation. - **updated_at** (string) - Timestamp of last update. #### Response Example ```json { "domain": "example.com", "license_key": "46fad906-bc51-435f-9929-db46cb4baf13", "status": "active", "expiration_date": "2025-01-01T00:00:00.000000Z", "is_trial": false, "is_lifetime": false, "deleted_at": null, "created_at": "2024-01-01T00:00:00.000000Z", "updated_at": "2024-01-01T00:00:00.000000Z" } ``` ### Notes - Requires `Authorization: Bearer YOUR_ACCESS_TOKEN` header. - `x-host` and `x-host-name` headers are required. ``` -------------------------------- ### Administer Licenses via REST API (CRUD Operations) Source: https://context7.com/laravel-ready/license-server/llms.txt Provides a full CRUD API for managing licenses, protected by admin middleware. Supports listing licenses with pagination and filtering, retrieving single licenses, updating existing licenses (status, domain, lifetime), and deleting licenses. Note that creating new licenses is not supported via this API and must be done programmatically using LicenseService::addLicense(). ```bash # List all licenses with pagination curl -X GET "https://your-server.com/api/license-server/licenses?perPage=15&q=example" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Accept: application/json" # Response { "success": true, "result": { "current_page": 1, "data": [ { "id": 1, "user_id": 1, "domain": "example.com", "license_key": "46fad906-bc51-435f-9929-db46cb4baf13", "status": "active", "expiration_date": "2025-01-01T00:00:00.000000Z", "is_trial": false, "is_lifetime": false, "expires_in": 365, "licensed_to": { /* product relationship */ } } ], "per_page": 15 } } # Get single license curl -X GET "https://your-server.com/api/license-server/licenses/1" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Accept: application/json" # Response { "success": true, "result": { "id": 1, "domain": "example.com", "license_key": "46fad906-bc51-435f-9929-db46cb4baf13", "status": "active" } } # Update license curl -X PUT "https://your-server.com/api/license-server/licenses/1" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "status": "suspended", "domain": "newdomain.com", "is_lifetime": true }' # Response { "success": true } # Delete license curl -X DELETE "https://your-server.com/api/license-server/licenses/1" \ -H "Authorization: Bearer ADMIN_TOKEN" # Response { "success": true } # Note: POST /licenses (create) is not supported via API # Use LicenseService::addLicense() programmatically instead { "success": false, "result": "You can not create a new license directly. Please use service class." } ``` -------------------------------- ### Authenticate and Obtain Access Token via REST API Source: https://context7.com/laravel-ready/license-server/llms.txt Client applications can authenticate using a license key and domain to obtain a Sanctum access token. This token is required for subsequent authenticated API calls. The API expects POST requests to the /api/license-server/auth/login endpoint with a JSON payload containing the license key and specific host headers. ```bash # Login endpoint curl -X POST "https://your-server.com/api/license-server/auth/login" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "x-host: example.com" \ -H "x-host-name: example.com" \ -d '{ "license_key": "46fad906-bc51-435f-9929-db46cb4baf13" }' # Success response (200) { "status": true, "message": "Successfully logged in.", "access_token": "abc123def456..." } # Error response - Invalid license (401) { "status": false, "message": "Invalid license key or lincese source." } # Error response - IP not allowed (401) { "status": false, "message": "This IP address is not allowed. Please contact the license provider." } # Note: x-host and x-host-name headers are required (DomainGuardMiddleware) ``` -------------------------------- ### Check License Status with LicenseService::checkLicenseStatus() Source: https://context7.com/laravel-ready/license-server/llms.txt Checks the current status of a given license key. Returns a string indicating the license's state, such as 'active', 'inactive', 'suspended', 'expired', or error codes like 'invalid-license-key' or 'no-license-found'. ```php [ /** * License checked event listener * * You can use this event to do something when a license is checked. * Also you can handle custom data with this listener. * * See the documentation for more information. * * Default: null */ 'license_checked' => App\Listeners\LicenseCheckedListener::class, ], ``` -------------------------------- ### Validate License Details via REST API Source: https://context7.com/laravel-ready/license-server/llms.txt This endpoint validates an authenticated license and retrieves its details. It requires an access token obtained from the login endpoint, sent in the Authorization header. The request includes custom data for event listeners and expects host headers. ```bash # Validate license endpoint curl -X POST "https://your-server.com/api/license-server/license" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \ -H "x-host: example.com" \ -H "x-host-name: example.com" \ -d '{ "custom_data": "any additional data for event listeners" }' # Success response { "domain": "example.com", "license_key": "46fad906-bc51-435f-9929-db46cb4baf13", "status": "active", "expiration_date": "2025-01-01T00:00:00.000000Z", "is_trial": false, "is_lifetime": false, "deleted_at": null, "created_at": "2024-01-01T00:00:00.000000Z", "updated_at": "2024-01-01T00:00:00.000000Z" } ``` -------------------------------- ### Retrieve Licenses by User ID with LicenseService::getLicenseByUserId() Source: https://context7.com/laravel-ready/license-server/llms.txt Fetches licenses associated with a specific user ID. This method can optionally filter the results to return a specific license if a license key is also provided. ```php user_id} has license: {$license->license_key}"; } ``` -------------------------------- ### Handle LicenseChecked Event Source: https://github.com/laravel-ready/license-server/blob/main/README.md Implement the `handle` method within your `LicenseCheckedListener` to access the license details and any custom data passed with the event. The event object provides access to `$event->license` and `$event->data`. ```php license, // $event->data, } } ``` -------------------------------- ### Query and Access License Model Attributes in PHP Source: https://context7.com/laravel-ready/license-server/llms.txt Interact with the License model to query licenses and access their attributes and relationships. The model provides computed attributes like 'status' and 'expires_in', and supports Sanctum tokens and soft deletes. ```php where('is_trial', false) ->with(['licensedTo', 'user', 'ipAddress']) ->get(); // License model attributes $license = License::find(1); $license->id; // Primary key $license->user_id; // Associated user $license->created_by; // Admin who created the license $license->domain; // Licensed domain (nullable) $license->license_key; // UUID key $license->status; // 'active', 'inactive', 'suspended', 'expired' (computed) $license->expiration_date; // Carbon datetime $license->is_trial; // boolean $license->is_lifetime; // boolean $license->expires_in; // Days until expiration (computed attribute) // Relationships $license->user; // BelongsTo User model $license->createdBy; // BelongsTo User who created $license->ipAddress; // HasOne IpAddress (for IP locking) $license->licensedTo; // HasOne LicensableProduct with product morphed // Sanctum token support (license acts as authenticatable) $token = $license->createToken('domain.com', ['license-access']); $license->tokens()->delete(); // Soft deletes are supported $license->delete(); // Soft delete $license->forceDelete(); // Permanent delete License::withTrashed()->get(); ``` -------------------------------- ### Admin License Management API Source: https://context7.com/laravel-ready/license-server/llms.txt Provides full CRUD (Create, Read, Update, Delete) operations for managing licenses. This API is protected by admin middleware, typically requiring Sanctum authentication with an admin token. ```APIDOC ## Admin License Management API ### Description Full CRUD API for managing licenses. Protected by admin middleware (auth:sanctum by default). ### Method GET, PUT, DELETE ### Endpoint `/api/license-server/licenses` (List, Create - not supported via API) `/api/license-server/licenses/{id}` (Get, Update, Delete) ### Parameters #### Path Parameters - **id** (integer) - Required - The unique identifier of the license. #### Query Parameters - **perPage** (integer) - Optional - Number of items per page for listing. - **q** (string) - Optional - Query parameter for searching licenses. #### Request Body (for PUT /licenses/{id}) - **status** (string) - Optional - The new status for the license (e.g., 'suspended'). - **domain** (string) - Optional - The new domain for the license. - **is_lifetime** (boolean) - Optional - Whether the license is lifetime. ### Request Example #### List all licenses ```bash curl -X GET "https://your-server.com/api/license-server/licenses?perPage=15&q=example" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Accept: application/json" ``` #### Get single license ```bash curl -X GET "https://your-server.com/api/license-server/licenses/1" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Accept: application/json" ``` #### Update license ```bash curl -X PUT "https://your-server.com/api/license-server/licenses/1" \ -H "Authorization: Bearer ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "status": "suspended", "domain": "newdomain.com", "is_lifetime": true }' ``` #### Delete license ```bash curl -X DELETE "https://your-server.com/api/license-server/licenses/1" \ -H "Authorization: Bearer ADMIN_TOKEN" ``` ### Response #### Success Response (List - 200) - **success** (boolean) - Indicates success. - **result** (object) - Contains pagination details and license data. - **current_page** (integer) - The current page number. - **data** (array) - An array of license objects. - **id** (integer) - License ID. - **user_id** (integer) - User ID associated with the license. - **domain** (string) - Licensed domain. - **license_key** (string) - The license key. - **status** (string) - License status. - **expiration_date** (string) - Expiration date. - **is_trial** (boolean) - Trial status. - **is_lifetime** (boolean) - Lifetime status. - **expires_in** (integer) - Days remaining until expiration. - **licensed_to** (object) - Product relationship details. - **per_page** (integer) - Items per page. #### Success Response (Get, Update, Delete - 200) - **success** (boolean) - Indicates success. - **result** (object or null) - For GET, contains license details. For PUT/DELETE, may contain a confirmation message or be null. #### Response Example (List) ```json { "success": true, "result": { "current_page": 1, "data": [ { "id": 1, "user_id": 1, "domain": "example.com", "license_key": "46fad906-bc51-435f-9929-db46cb4baf13", "status": "active", "expiration_date": "2025-01-01T00:00:00.000000Z", "is_trial": false, "is_lifetime": false, "expires_in": 365, "licensed_to": { /* product relationship */ } } ], "per_page": 15 } } ``` #### Response Example (Get Single License) ```json { "success": true, "result": { "id": 1, "domain": "example.com", "license_key": "46fad906-bc51-435f-9929-db46cb4baf13", "status": "active" } } ``` #### Response Example (Update/Delete) ```json { "success": true } ``` #### Error Response (Create - Not Supported) - **success** (boolean) - Always false for creation via API. - **result** (string) - Message indicating creation is not supported via API. #### Error Response Example (Create) ```json { "success": false, "result": "You can not create a new license directly. Please use service class." } ``` ### Notes - POST `/licenses` (create) is not supported via API. Use `LicenseService::addLicense()` programmatically instead. - Requires `Authorization: Bearer ADMIN_TOKEN` header. ``` -------------------------------- ### Register Custom License Validation Controller Source: https://github.com/laravel-ready/license-server/blob/main/README.md Configure the license server to use your custom license validation controller. This involves specifying the controller class and method within the `config/license-server.php` configuration file. ```php /** * Custom controllers for License Server */ 'controllers' => [ /** * License validation controller * * You can use this controller to handle license validating * * See the documentation for more information. * */ 'license_validation' => [ App\Http\Controllers\LicenseController::class, 'licenseValidate' ] ] ``` -------------------------------- ### Check License Status Source: https://github.com/laravel-ready/license-server/blob/main/README.md Checks the current status of a given license key. The status can be 'active', 'inactive', 'suspended', 'expired', 'invalid-license-key', or 'no-license-found'. ```APIDOC ## POST /api/license-server/check-status ### Description Checks the status of a license using its license key. ### Method POST ### Endpoint /api/license-server/check-status ### Parameters #### Request Body - **licenseKey** (string) - Required - The license key to check. ### Request Example ```json { "example": { "licenseKey": "46fad906-bc51-435f-9929-db46cb4baf13" } } ``` ### Response #### Success Response (200) - **status** (string) - The status of the license (e.g., 'active', 'inactive', 'suspended', 'expired', 'invalid-license-key', 'no-license-found'). #### Response Example ```json { "example": { "status": "active" } } ``` ``` -------------------------------- ### Check License Status Source: https://github.com/laravel-ready/license-server/blob/main/README.md Verify the current status of a license using its unique key. This function returns one of several possible status strings: 'active', 'inactive', 'suspended', 'expired', 'invalid-license-key', or 'no-license-found'. ```php // license key in uuid format $licenseKey = "46fad906-bc51-435f-9929-db46cb4baf13"; // check license status $licenseStatus = LicenseService::checkLicenseStatus($licenseKey); ``` -------------------------------- ### Add Licensable Trait to Product Model Source: https://github.com/laravel-ready/license-server/blob/main/README.md Integrates the Licensable trait into your Product model, enabling it to be associated with licenses. This allows your products to be managed by the license server. ```php user()' will be is our license $_license = $license->select( 'domain', 'license_key', 'status', 'expiration_date', 'is_trial', 'is_lifetime' )->where([ ['id', '=', auth()->user()->id], ['is_trial', '!=', true] ])->first(); $data = $request->input(); // event will be fired after license is checked // this part depends to your logic, you can remove it or change it Event::dispatch(new LicenseChecked($_license, $data)); $_license->appent_some_data = 'some data and date now -> ' . now(); return $_license; } } ``` -------------------------------- ### Make Eloquent Model Licensable in Laravel Source: https://context7.com/laravel-ready/license-server/llms.txt Demonstrates how to make a Laravel Eloquent model licensable by using the `Licensable` trait and accessing its relationships and properties. ```php licensable; // Get the license associated with this product $license = $product->licensable->license; // Check if product is licensed if ($product->licensed) { echo "Product is licensed"; } ``` -------------------------------- ### Update License Status using LicenseService in PHP Source: https://context7.com/laravel-ready/license-server/llms.txt Allows updating the status of a license to 'suspended', 'active', or 'inactive'. This method only operates on non-expired licenses. It returns the updated license object or null if the license is expired or the key is invalid. ```php user() returns the License model $_license = $license->select( 'domain', 'license_key', 'status', 'expiration_date', 'is_trial', 'is_lifetime' )->where([ ['id', '=', auth()->user()->id], ['is_trial', '!=', true] // Custom: exclude trial licenses ])->first(); $data = $request->input(); // Dispatch event for listeners Event::dispatch(new LicenseChecked($_license, $data)); // Add custom data to response $_license->server_time = now(); $_license->custom_message = 'License validated successfully'; return $_license; } } // Register in config/license-server.php 'controllers' => [ 'license_validation' => [ App\Http\Controllers\CustomLicenseController::class, 'licenseValidate' ] ], ``` -------------------------------- ### LicenseService::setLicenseStatus() Source: https://context7.com/laravel-ready/license-server/llms.txt Updates the status of a license. This method only works on non-expired licenses and can set the status to 'active', 'inactive', or 'suspended'. It returns null if the license is expired or the key is invalid. ```APIDOC ## LicenseService::setLicenseStatus() ### Description Updates the status of a license. Only works on non-expired licenses. ### Method *Programmatic (PHP)* ### Parameters #### Path Parameters *None* #### Query Parameters *None* #### Request Body *None* ### Request Example ```php