Referenceable – Generate Reference Numbers in Laravel | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    Referenceable: Generate Clean and Customizable Reference Numbers in Laravel        On this page       1. [  The Problem With Reference Numbers ](#the-problem-with-reference-numbers)
2. [  Meet Referenceable ](#meet-referenceable)
3. [  1. Random References ](#1-random-references)
4. [  2. Sequential References ](#2-sequential-references)
5. [  3. Template-Based References ](#3-template-based-references)
6. [  Getting Started ](#getting-started)
7. [  Model-Level Configuration ](#model-level-configuration)
8. [  Multi-Tenant Applications ](#multi-tenant-applications)
9. [  Collision Handling and Validation ](#collision-handling-and-validation)
10. [  Working With References ](#working-with-references)
11. [  Artisan Commands ](#artisan-commands)
12. [  Where Can Referenceable Be Used? ](#where-can-referenceable-be-used)
13. [  Built for Real Laravel Applications ](#built-for-real-laravel-applications)
14. [  Why I Built It ](#why-i-built-it)
15. [  Try Referenceable ](#try-referenceable)

  ![Referenceable: Generate Clean and Customizable Reference Numbers in Laravel](https://cdn.msaied.com/656/01M27ZF9VSQC7BQC96HV2KABSD.png)

 [  Laravel ](https://msaied.com/articles?category=laravel) [  Open Source ](https://msaied.com/articles?category=open-source) [  Composer Pacakge ](https://msaied.com/articles?category=composer-pacakge) [  PHP ](https://msaied.com/articles?category=php) 

 Referenceable: Generate Clean and Customizable Reference Numbers in Laravel 
=============================================================================

     11 Sep 2026      8 min read    ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said  

       Table of contents

  15 sections  

1. [  01   The Problem With Reference Numbers  ](#the-problem-with-reference-numbers)
2. [  02   Meet Referenceable  ](#meet-referenceable)
3. [  03   1. Random References  ](#1-random-references)
4. [  04   2. Sequential References  ](#2-sequential-references)
5. [  05   3. Template-Based References  ](#3-template-based-references)
6. [  06   Getting Started  ](#getting-started)
7. [  07   Model-Level Configuration  ](#model-level-configuration)
8. [  08   Multi-Tenant Applications  ](#multi-tenant-applications)
9. [  09   Collision Handling and Validation  ](#collision-handling-and-validation)
10. [  10   Working With References  ](#working-with-references)
11. [  11   Artisan Commands  ](#artisan-commands)
12. [  12   Where Can Referenceable Be Used?  ](#where-can-referenceable-be-used)
13. [  13   Built for Real Laravel Applications  ](#built-for-real-laravel-applications)
14. [  14   Why I Built It  ](#why-i-built-it)
15. [  15   Try Referenceable  ](#try-referenceable)

       Referenceable: A Better Way to Generate Reference Numbers in Laravel
====================================================================

Almost every business application eventually needs human-friendly reference numbers.

An order might need:

```text
ORD-2026-0001

```

An invoice might use:

```text
INV-001024

```

A support ticket could look like:

```text
TKT-X7K92P

```

At first, generating these values seems simple.

Add a column, generate a random string or increment a number, save it, and move on.

But as the application grows, the requirements usually grow with it.

You may need different formats for different models, yearly or monthly sequence resets, tenant-specific numbering, validation, collision handling, custom prefixes, or references that contain dates and other dynamic values.

That is exactly the problem I wanted to solve when I created **Referenceable**.

Referenceable is an open-source Laravel package for generating flexible, customizable, and reliable reference numbers for Eloquent models.

GitHub:

---

The Problem With Reference Numbers
----------------------------------

Database IDs are excellent for databases:

```text
1
2
3
18492

```

But they are usually not great identifiers to expose to customers or employees.

Imagine receiving this confirmation:

```text
Your order number is #18374

```

Now compare it with:

```text
Your order number is ORD-2026-018374

```

The second version immediately provides more context and feels much more appropriate for a production business application.

You can certainly implement this yourself.

The problem is that reference generation quickly becomes repetitive.

You start with something like:

```php
$order->reference = 'ORD-' . Str::random(8);

```

Then requirements start arriving:

- References must be unique.
- Invoice numbers should be sequential.
- Sequences should restart every year.
- Orders need a different format.
- Some references need the current month.
- Characters such as `0`, `O`, `1`, and `I` should be excluded.
- Each organization should have its own sequence.
- Existing records need references.
- Generated references need validation.

At this point, something that originally looked like a few lines of code has become its own subsystem.

Referenceable moves that responsibility into a reusable package.

---

Meet Referenceable
------------------

Referenceable provides three main strategies for generating model references:

### 1. Random References

Perfect when the sequence itself is not important.

For example:

```text
ORD-AB12CD
TKT-X7K92P
USR-M4NP8Q

```

You can configure the prefix, length, allowed characters, excluded characters, letter case, separator, and more.

For example:

```php
protected $referenceStrategy = 'random';
protected $referencePrefix = 'ORD';
protected $referenceLength = 6;
protected $referenceCase = 'upper';

```

Which can generate something like:

```text
ORD-AB12CD

```

---

2. Sequential References
------------------------

For invoices, purchase orders, quotations, or other records where sequential numbering makes more sense, Referenceable can automatically manage the counter.

For example:

```php
protected $referenceStrategy = 'sequential';
protected $referencePrefix = 'INV';

protected $referenceSequential = [
    'start' => 1000,
    'min_digits' => 6,
    'reset_frequency' => 'yearly',
];

```

This can produce:

```text
INV-001000
INV-001001
INV-001002

```

Sequences can be configured to reset:

```text
Never
Daily
Monthly
Yearly

```

This makes the strategy useful for many accounting, ERP, CRM, booking, ticketing, and internal business systems.

---

3. Template-Based References
----------------------------

This is probably my favorite part of the package.

Instead of being restricted to one predefined structure, you can define your own reference template.

For example:

```php
protected $referenceStrategy = 'template';

protected $referenceTemplate = [
    'format' => '{PREFIX}{YEAR}{MONTH}{SEQ}',
    'sequence_length' => 4,
];

protected $referencePrefix = 'ORD';

```

This allows references such as:

```text
ORD2026090001
ORD2026090002
ORD2026090003

```

Referenceable supports placeholders including:

```text
{PREFIX}
{SUFFIX}
{YEAR}
{YEAR2}
{MONTH}
{DAY}
{SEQ}
{RANDOM}
{MODEL}
{TIMESTAMP}

```

This means you can create structures such as:

```text
ORD-2026-09-0001

```

or:

```text
INV-26-000001

```

or even:

```text
TICKET-202609-X7K9

```

without rebuilding your reference-generation logic every time.

---

Getting Started
---------------

Installation is straightforward.

Install the package using Composer:

```bash
composer require eg-mohamed/referenceable

```

Then run:

```bash
php artisan referenceable:install

```

The installation command prepares the package configuration and required database structures.

Next, add a reference column to your model's table:

```php
Schema::create('orders', function (Blueprint $table) {
    $table->id();

    $table->string('reference')
        ->unique()
        ->index();

    $table->timestamps();
});

```

Then add the `HasReference` trait to your model:

```php
use MohamedSaid\Referenceable\Traits\HasReference;

class Order extends Model
{
    use HasReference;
}

```

That's basically it.

Now when you create an order:

```php
$order = Order::create([
    'customer_id' => 1,
    'total' => 99.99,
]);

```

Referenceable can automatically assign its reference:

```php
echo $order->reference;

```

For example:

```text
AB12CD34

```

From there, you can customize the generation behavior for each model.

---

Model-Level Configuration
-------------------------

One important goal while building Referenceable was avoiding a one-size-fits-all configuration.

Different models usually have different requirements.

An `Invoice` may need sequential references while an `Order` uses a template and a `Ticket` uses a random code.

Referenceable allows these settings to live directly on the model.

For example:

```php
protected $referenceColumn = 'order_number';

protected $referenceStrategy = 'template';

protected $referencePrefix = 'ORD';

protected $referenceSeparator = '-';

protected $referenceTemplate = [
    'format' => '{PREFIX}{YEAR}{MONTH}{SEQ}',
    'sequence_length' => 4,
];

```

You still have global defaults available in:

```text
config/referenceable.php

```

So applications can choose between global conventions and model-specific customization.

---

Multi-Tenant Applications
-------------------------

Multi-tenancy introduces another interesting problem.

Imagine an application containing multiple companies.

Company A may need:

```text
INV-000001

```

while Company B should also be able to have:

```text
INV-000001

```

The references are unique within the organization rather than globally.

Referenceable supports tenant-aware uniqueness:

```php
class Order extends Model
{
    use HasReference;

    protected $referenceUniquenessScope = 'tenant';

    protected $referenceTenantColumn = 'company_id';
}

```

This makes the package particularly useful in SaaS applications where each tenant maintains its own numbering system.

---

Collision Handling and Validation
---------------------------------

Random reference generation introduces another question:

What happens if the same reference is generated twice?

Referenceable includes collision detection and configurable collision strategies.

For example:

```php
protected $referenceCollisionStrategy = 'retry';
protected $referenceMaxRetries = 100;

```

References can also be validated using configurable rules, lengths, and regular expressions.

For example:

```php
protected $referenceValidation = [
    'pattern' => '/^ORD-\d{4}-\w{6}$/',
    'min_length' => 8,
    'max_length' => 20,
];

```

This keeps reference generation predictable instead of relying on application code scattered across controllers, observers, services, and models.

---

Working With References
-----------------------

Referenceable also provides useful APIs for working with generated references.

Generate one manually:

```php
$reference = $order->generateReference();

```

Regenerate an existing reference:

```php
$order->regenerateReference(save: true);

```

Check whether a model already has one:

```php
if ($order->hasReference()) {
    // ...
}

```

Validate it:

```php
$order->validateReference();

```

And find a model directly using its reference:

```php
$order = Order::findByReference('ORD-123456');

```

There are also query scopes for filtering models with or without references and filtering by reference prefixes.

---

Artisan Commands
----------------

Another requirement I wanted to cover was maintaining references after an application was already running.

Referenceable therefore provides several Artisan commands.

Generate missing references:

```bash
php artisan referenceable:generate "App\Models\Order"

```

Preview the operation first:

```bash
php artisan referenceable:generate "App\Models\Order" --dry-run

```

Validate existing references:

```bash
php artisan referenceable:validate "App\Models\Order"

```

View reference statistics:

```bash
php artisan referenceable:stats "App\Models\Order"

```

And regenerate references when necessary:

```bash
php artisan referenceable:regenerate "App\Models\Order" --id=123

```

This becomes particularly useful when introducing Referenceable into an existing application containing thousands or millions of records.

---

Where Can Referenceable Be Used?
--------------------------------

Reference numbers appear in almost every type of business software.

Some common examples include:

**E-commerce**

```text
ORD-2026-000154

```

**Invoices**

```text
INV-000248

```

**Support tickets**

```text
TKT-X72K91

```

**Bookings**

```text
BKG-202609-0042

```

**Purchase orders**

```text
PO-26-000145

```

**Shipments**

```text
SHP-A7DK92

```

**CRM opportunities**

```text
LEAD-2026-0182

```

**Event registrations**

```text
REG-2026-X82LQ

```

The goal isn't to decide what your reference numbers should look like.

The goal is to give you enough flexibility to define that yourself.

---

Built for Real Laravel Applications
-----------------------------------

Referenceable currently supports Laravel 10 through Laravel 13 and includes functionality for:

- Random reference generation
- Sequential numbering
- Template-based generation
- Daily, monthly, and yearly sequence resets
- Configurable prefixes and suffixes
- Custom separators
- Custom character sets
- Excluded characters
- Reference validation
- Uniqueness checking
- Automatic collision handling
- Multi-tenant reference generation
- Batch operations
- Artisan management commands
- Configuration caching
- Database transactions

The package is open source and released under the MIT license.

---

Why I Built It
--------------

A lot of open-source packages start with the same thought:

> "I've implemented this too many times."

Reference generation was one of those things for me.

Across different systems, I kept encountering slightly different versions of the same requirement.

Orders needed references.

Invoices needed references.

Tickets needed references.

Registrations needed references.

And every project had slightly different rules.

Instead of continuing to rebuild the same concept, I wanted a reusable implementation that could handle simple requirements while still being flexible enough for more complex applications.

That became **Referenceable**.

---

Try Referenceable
-----------------

If you're building a Laravel application and find yourself writing custom logic for order numbers, invoice numbers, tickets, bookings, registrations, or other business identifiers, give Referenceable a try.

Install it with:

```bash
composer require eg-mohamed/referenceable

```

You can find the source code, documentation, examples, issues, and contribution guidelines on GitHub:

****

If the package saves you some development time, consider giving the repository a ⭐.

And because it's open source, contributions, bug reports, ideas, and feature requests are always welcome.

Happy coding! 🚀

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Freferenceable-generate-clean-and-customizable-reference-numbers-in-laravel&text=Referenceable%3A+Generate+Clean+and+Customizable+Reference+Numbers+in+Laravel) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Freferenceable-generate-clean-and-customizable-reference-numbers-in-laravel) 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![Testing Filament Resources, Actions, and Form Assertions with Pest](https://cdn.msaied.com/655/efd33245cffa553c1dffba29721e0139.png) filament pest testing 

### Testing Filament Resources, Actions, and Form Assertions with Pest

A practical guide to writing reliable Pest tests for Filament v3 resources — covering table actions, form subm...

  ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said 

 11 Sep 2026     4 min read  

  Read    

 ](https://msaied.com/articles/testing-filament-resources-actions-and-form-assertions-with-pest-4) [ ![PayZephyr: One Payment API for Stripe, Paystack, and PayPal in Laravel](https://cdn.msaied.com/657/2cc520b20de249b38bc52120605ff447.png) Laravel Payments Stripe 

### PayZephyr: One Payment API for Stripe, Paystack, and PayPal in Laravel

PayZephyr is a Laravel package that wraps eight payment providers—Stripe, Paystack, PayPal, Flutterwave, and m...

  ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said 

 11 Sep 2026     3 min read  

  Read    

 ](https://msaied.com/articles/payzephyr-one-payment-api-for-stripe-paystack-and-paypal-in-laravel) [ ![Bifrost Turns One: AI Builds, MCP Server, and Automated Workflows for NativePHP](https://cdn.msaied.com/653/e105bc3450f63955d42ed8feeb5a60f7.png) NativePHP Bifrost MCP 

### Bifrost Turns One: AI Builds, MCP Server, and Automated Workflows for NativePHP

Bifrost, the NativePHP build and distribution service, celebrates its first anniversary and 10,000 builds with...

  ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said 

 10 Sep 2026     4 min read  

  Read    

 ](https://msaied.com/articles/bifrost-turns-one-ai-builds-mcp-server-and-automated-workflows-for-nativephp) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
