omaressaouaf/laravel-id-generator
Generate unique, customizable IDs for your Laravel models with prefixes, suffixes, dates, and sequential or random segments. Ideal for invoice numbers, order IDs, and Stripe-style identifiers, with concurrency-safe generation out of the box.
composer require omaressaouaf/laravel-id-generator — auto-discovered via package manifest, no manual provider registration.php artisan vendor:publish --tag="id-generator-config", then read config/id-generator.php top to bottom. That file (not the README) is the real API surface: a default key plus a generators map where each entry defines its prefix, length and generation strategy.IdGenerator::generate() for the default generator and IdGenerator::use('invoice')->generate() for a named one.composer update and nothing else.One named generator per domain. Resist using the default generator everywhere. Declare invoice, customer, ticket in the config so the format for each lives in one reviewable place, and let callers ask for the generator by name. When finance asks for a new prefix, it's a one-line config diff instead of a grep across the codebase.
Assign in a model event or observer, not in the controller. Generating the ID inside creating/booted guarantees every write path (HTTP, queued job, importer, artisan command, seeder) gets a value. Controllers that generate IDs inevitably miss the one path that isn't a controller.
Keep your auto-increment primary key and add a unique number column. Replacing the PK with a generated string is a much bigger migration than it looks — foreign keys, route() model binding behaviour, and index size all shift. Add a string column with a unique() index and treat the package output as a business reference, not the identity.
Treat uniqueness as the database's job. The unique index is the source of truth; the generator produces a candidate. Wrap creation in a small retry (catch the QueryException for the unique violation and regenerate) rather than trying to prove uniqueness in application code — that reasoning breaks the moment you run more than one worker.
Testing. Don't assert exact strings — assert shape. A regex or length/prefix check against the generator's rules survives config edits and clock changes. For determinism, freeze or swap the generator binding in the container so tests don't depend on randomness, and add one test that hits the real generator to prove the config itself is valid.
API resources and form requests. The generated ID is an output, never an input. Strip it from $fillable / validation rules so clients can't supply their own invoice number; expose it only in the resource.
Multi-tenant setups. Either define one generator per tenant (prefix carries the tenant slug) or resolve the prefix at runtime from the tenant context. Keep the suffix format identical across tenants so support staff can read an ID and know which tenant it belongs to.
config/id-generator.php edits are invisible until php artisan config:clear (or a config:cache re-run). This is the single most common "the package is broken" report.NOT NULL — in that order.composer why-not laravel/framework 13.* before bumping, and check anything that pins illuminate/* or ships compiled extensions. Also confirm your own CI matrix actually has a PHP 8.5 image — the release notes outrun most CI providers' defaults.generators map. That's the supported seam — avoid subclassing the facade or monkey-patching internals.How can I help you explore Laravel packages today?