madebyclowd / laravel-auto-sequence
Automatically generate sequential invoice/order numbers (like INV-2026-0001) for Laravel Eloquent models. Safe from duplicates even under heavy concurrent traffic.
Package info
github.com/madebyclowd/laravel-auto-sequence
pkg:composer/madebyclowd/laravel-auto-sequence
Requires
- php: ^8.2
- illuminate/database: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.13
- orchestra/testbench: ^9.0|^10.0|^11.0
- phpunit/phpunit: ^10.0|^11.0|^12.0|^13.0
Suggests
- laravel/boost: Auto-discovers this package's AI guidelines and agent skill from resources/boost/ — no extra setup needed.
README
This package makes numbers for your Laravel models, like INV-2026-0001 or ORD-999. Each new number is bigger than the last one.
It works on its own. Two records never get the same number, even if thousands of people place an order at the exact same second.
Why not just use the model's id?
The database id (1, 2, 3...) is fine inside your app. But don't show it to your users. Here is why:
- It leaks data. Your customers can guess how many orders or invoices you have.
- It is unpredictable. On your computer it may start at 1. On the live server it may start at 14,000. You can't control it.
- It is boring. You can't add the year, a branch code, or your own prefix. You can't turn
id = 5intoINV-2026-NY-0005.
This package makes a separate, nicer number for you, like invoice_number. It also makes sure two requests at the same time never get the same number.
Where teams actually use this
- Online stores: order numbers during flash sales, with no crashes and no duplicates.
- Invoicing: sequential invoice numbers that meet tax or audit rules.
- SaaS billing: each customer sees their own numbers start at
1. - Multi-branch retail: each store gets its own daily receipt numbers.
- Support desks: short, permanent ticket numbers.
- Manufacturing: batch or serial numbers that reset on a fiscal year.
Full examples with config for each: Real-World Use Cases.
Quick Start
Follow these steps in order. This example numbers an Invoice model.
Step 1: Install the package
composer require madebyclowd/laravel-auto-sequence
Step 2: Run the setup command
It asks a few yes/no questions. Press Enter each time to pick the normal answer. It creates two small database tables the package needs.
php artisan sequence:install
Step 3: Add a number column to your table
Make a new migration for the table you want to number (here, invoices):
php artisan make:migration add_number_to_invoices_table --table=invoices
Open that new migration file and add one line inside the up() method:
$table->string('number')->nullable();
Run the migration:
php artisan migrate
Step 4: Tell the model to use the package
Open your model file (app/Models/Invoice.php). Add implements Sequenceable to the class, and use HasSequenceNumber; inside it:
use MadeByClowd\AutoSequence\Contracts\Sequenceable; use MadeByClowd\AutoSequence\Traits\HasSequenceNumber; use Illuminate\Database\Eloquent\Model; class Invoice extends Model implements Sequenceable { use HasSequenceNumber; }
Step 5: Describe how the number should look
Still inside the Invoice class, add a getSequenceConfig() method:
class Invoice extends Model implements Sequenceable { use HasSequenceNumber; public function getSequenceConfig(): array { return [ 'number' => [ 'module' => 'invoice', 'type_code' => 'INV', 'period' => 'monthly', 'format_template' => '{type_code}-{YYYY}-{MM}-{seq:5}', ], ]; } }
What each line means:
'number': the column this fills in. It must match the column you added in Step 3.module: a name for this counter. Give related things, like all invoices, the same module name.type_code: the prefix text you want to show, likeINV.period: when the counter goes back to1.monthlymeans it resets every month.format_template: the shape of the final number.{seq:5}means the counter, padded to 5 digits. See Format Tokens for every piece you can use here.
Step 6: Create a record
$invoice = Invoice::create([...]); // don't set 'number' yourself, it fills in on its own echo $invoice->number; // "INV-2026-06-00001"
Done. Every new Invoice now gets a safe number that goes up by itself.
Features
- No duplicate numbers, ever. The package locks the counter (using the database or Redis). Two requests at the same time can never get the same number.
- Fewer database trips (optional). The package can hand out numbers in batches, like 50 at a time, and keep them in memory. This means fewer trips to the database.
- Separate counters for separate things. Invoices, orders, and each branch or store can each have their own counter. They never mix.
- Counters that reset by themselves. Start back at
0001every month, every year, or on your own schedule (like a fiscal year). No cron job needed. - Smart prefixes that change per record. Get the prefix (like
INVorJKT) from related data. You don't have to hardcode it. - Build the number any way you want. Mix pieces like
{YYYY},{MM},{seq:5}, or a random code into one format. - A command to fix a broken counter. Run
php artisan sequence:verify --repairto match the counter with your real data. - Events for every important moment.
SequenceGenerated,SequenceExhausted,SequenceRecycled,SequenceResetPerformed.
Requirements
- PHP 8.2+
- Laravel 11, 12, or 13 (
illuminate/supportandilluminate/database)
Documentation
The docs/ folder covers every feature step by step:
- Real-World Use Cases
- Basic Usage
- Format Tokens
- Advanced Usage (custom prefixes, separate counters per tenant, custom reset dates, soft deletes)
- Events
- Manual Generation (Facade)
- Artisan Commands
- Configuration
- Troubleshooting / FAQ
License
The MIT License (MIT). Please see the LICENSE file for more information.