Download the PHP package devravik/laravel-licensing without Composer

On this page you can find all versions of the php package devravik/laravel-licensing. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-licensing

Laravel Licensing

Latest Version on Packagist Total Downloads Tests PHP Version License

A production-ready Laravel package for generating, managing, activating, and validating software licenses directly inside your application.

License keys are hashed before storage (never plaintext in the database), activations are seat-controlled, and the entire lifecycle creation, validation, activation, revocation, and expiry is covered by typed exceptions and dispatchable events.


Starter Kit

New to this package? Check out the Laravel Licensing Starter a complete working example that demonstrates how to use this package in a real Laravel application.

The starter kit includes:

Perfect for understanding how to integrate this package into your own application!


Requirements

Dependency Version
PHP ^8.1 (PHP 8.2+ required for Laravel 11 / 12)
Laravel ^10.0 \| ^11.0 \| ^12.0

Installation

1. Install via Composer

2. Publish the config

3. Publish the migrations

4. Run the migrations

The package auto-registers its service provider via Laravel's package discovery. No manual registration is required.


Configuration

After publishing, the config file lives at config/license.php:

Option Type Default Description
license_model string License::class Eloquent model for licenses
activation_model string Activation::class Eloquent model for activations
key_length int 32 Length of generated license keys (chars)
hash_keys bool true Hash keys with bcrypt before storage
default_expiry_days int\|null 365 Default license duration; null = no expiry
grace_period_days int 7 Days of temporary validity after expiry; 0 = disabled
license_generation string 'random' Generation strategy: 'random' or 'signed'
signature.public_key string\|null null Ed25519 public key (file path or base64 string)
signature.private_key string\|null null Ed25519 private key (file path or base64 string)

Environment variables:


Usage

Creating a License

Use the HasLicenses trait on any Eloquent model that should own licenses, then build with the fluent API:

Builder reference:

Method Description Required
for(Model $owner) Bind the license to an Eloquent model Yes
product(string $product) Set the product name or tier Yes
seats(int $count) Maximum activations allowed (default: 1) No
expiresInDays(int $days) Expiry relative to now No
expiresAt(Carbon $date) Explicit expiry date No
create() Persist and return the license Yes

If neither expiresInDays() nor expiresAt() is called, the value from config('license.default_expiry_days') is used.


Validating a License


Activating a License

Bind a license to a domain, IP address, machine ID, or any identifier. Each binding consumes one seat.


Deactivating a License

Remove an activation to free up a seat:


Revoking a License

Immediately and permanently invalidate a license:


Checking License Status


Facade Reference

Method Signature Returns Description
for for(Model $owner) LicenseBuilder Begin building a license
validate validate(string $key) License Validate and return license; throws on failure
activate activate(string $key, string $binding) Activation Activate a license against a binding
deactivate deactivate(string $key, string $binding) bool Remove an activation binding
revoke revoke(string $key) bool Permanently revoke a license
find find(string $key) License\|null Find a license without validation

Artisan Commands

The package provides comprehensive Artisan commands for managing licenses:

Generate License Keys

Generate Ed25519 key pairs for signed license verification:

Options:

License Status

Check package configuration and status:

List Licenses

List all licenses with optional filtering:

Options:

Show License

Display detailed information about a specific license:

Options:

Create License

Create a new license interactively or via options:

Options:

Revoke License

Revoke a license by key or ID:

Options:

Activate License

Activate a license for a binding:

Options:

Deactivate License

Remove an activation binding:

Options:

License Statistics

Display license and activation statistics:

Options:

Output includes:


Middleware

The package ships two middleware aliases that are registered automatically.

Protect routes requiring a specific product

Protect routes requiring any valid license

The middleware reads the license key from the X-License-Key request header (or license_key query/body parameter).

Middleware Responses

Failure Reason HTTP Status
No key provided 401 Unauthorized
Key not found 404 Not Found
Revoked or expired 403 Forbidden
Wrong product tier 403 Forbidden
Seat limit exceeded 422 Unprocessable Entity

For Accept: application/json requests the middleware returns:

For web requests, abort() is called with the appropriate status code.

You can customise the response by extending AbstractLicenseMiddleware and overriding denyResponse().


Events

Event Fired When Properties
LicenseCreated create() is called $event->license
LicenseActivated activate() is called $event->license, $event->activation
LicenseDeactivated deactivate() is called $event->license, $event->binding
LicenseRevoked revoke() is called $event->license
LicenseExpired Dispatched manually from a scheduled command $event->license

LicenseExpired is intentionally not dispatched automatically it should be fired from a scheduled command so you control when and how expiration is processed:

Registering Listeners


Exceptions

All exceptions extend LicenseManagerException, so you can catch them collectively or individually.

Exception Thrown When getStatusCode()
InvalidLicenseException Key does not match any record 404
LicenseExpiredException Expired beyond grace period 403
LicenseRevokedException License has been revoked 403
SeatLimitExceededException All activation seats occupied 422
LicenseAlreadyActivatedException Binding already exists for this license 409
LicenseManagerException Base exception (catch-all) 500

Global Exception Handler


Database Schema

licenses

Column Type Notes
id bigint PK Auto-increment
key varchar(255) Bcrypt hash of the raw key (or plaintext if hash_keys=false)
lookup_token varchar(64) nullable, indexed SHA-256 of raw key; used for O(log n) pre-filtering before bcrypt check
product varchar(255) indexed Product name or tier
owner_id bigint indexed Polymorphic FK
owner_type varchar(255) Polymorphic type
seats int default 1 Maximum activations allowed
expires_at timestamp nullable Expiration timestamp
revoked_at timestamp nullable Set when revoked; null = active
created_at / updated_at timestamp Laravel timestamps

license_activations

Column Type Notes
id bigint PK Auto-increment
license_id bigint FK Cascades on delete
binding varchar(255) Domain, IP, machine ID, or custom string
activated_at timestamp When activation occurred
created_at / updated_at timestamp Laravel timestamps

A unique composite index on (license_id, binding) prevents duplicate activations.


Advanced Usage

Polymorphic Ownership

Licenses can belong to any model not just users. Add the HasLicenses trait:

Querying Licenses

Custom License Model

Update config/license.php:

Custom Activation Model

Using in Controllers


Security

Production checklist:

  1. Keep hash_keys = true never disable in production.
  2. Use HTTPS for all endpoints that transmit or receive license keys.
  3. Rate-limit validation and activation endpoints to prevent brute-force guessing.
  4. Use the provided events to audit all license operations.
  5. Never log raw license keys.
  6. For signed licenses, store private keys securely and never commit them to version control.

Testing

The package test suite runs against MySQL:

Create the MySQL test database first:

Example Test


Signature-Based License Verification (v1.1+)

v1.1 adds optional Ed25519 signature-based license verification for offline and tamper-resistant validation scenarios.

Enabling Signed Licenses

Set LICENSE_GENERATION=signed in your .env file and provide Ed25519 key pair:

Or use file paths:

Generating Key Pairs

Generate an Ed25519 key pair using the Artisan command:

This will generate a new key pair and display the values to add to your .env file.

Options:

Example:

Manual Generation (Alternative):

If you prefer to generate keys manually using PHP:

How It Works

When license_generation is set to 'signed':

  1. Generation: License keys are created by signing a JSON payload (product, seats, expiry, owner info) with the private key using Ed25519.
  2. Format: Keys are base64-encoded strings containing base64(message . '.' . signature).
  3. Verification: During validation, the signature is verified using the public key before database lookup.
  4. Storage: Signed licenses are still stored in the database (hashed) for seat management, activations, and revocation tracking.

Benefits

Example


Changelog

Please see CHANGELOG.md for a full release history.


Contributing

Contributions are welcome. Please:

  1. Fork the repository and create a feature branch from main.
  2. Write tests for all new functionality.
  3. Follow PSR-12 and run composer format before submitting.
  4. Ensure composer test and composer analyse pass.
  5. Open a pull request with a clear description of the change.

Pull requests without tests will not be merged.

When reporting a bug, please include your PHP and Laravel version, the package version, steps to reproduce, and any relevant stack traces.


Security Vulnerabilities

Please do not report security vulnerabilities via GitHub Issues. Email [email protected] with the subject line [SECURITY] devravik/laravel-licensing <brief description>. You will receive a response within 48 hours.

See SECURITY.md for details.


Maintainer

Ravi K Gupta


License

The MIT License (MIT). Please see LICENSE for more information.


All versions of laravel-licensing with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
illuminate/console Version ^10.0|^11.0|^12.0
illuminate/contracts Version ^10.0|^11.0|^12.0
illuminate/database Version ^10.0|^11.0|^12.0
illuminate/events Version ^10.0|^11.0|^12.0
illuminate/hashing Version ^10.0|^11.0|^12.0
illuminate/routing Version ^10.0|^11.0|^12.0
illuminate/support Version ^10.0|^11.0|^12.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package devravik/laravel-licensing contains the following files

Loading the files please wait ...