Referenceable – Generate Reference Numbers in Laravel | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. [Laravel](https://www.msaied.com/public/articles?category=laravel)
6. /
7. Referenceable: Generate Clean and Customizable Reference Numbers in Laravel

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

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

 Referenceable is an open-source Laravel package for generating clean, customizable reference numbers for Eloquent models using random, sequential, or template-based strategies, with support for sequence resets, multi-tenancy, validation, and collision handling.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 11 Sep 2026 · Updated 11 Sep 2026 · 8 min read

ShareCopy linkCopied

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

  On this page +1. [Referenceable: A Better Way to Generate Reference Numbers in Laravel](#referenceable-a-better-way-to-generate-reference-numbers-in-laravel)
2. [The Problem With Reference Numbers](#the-problem-with-reference-numbers)
3. [Meet Referenceable](#meet-referenceable)
4. [1. Random References](#1-random-references)
5. [2. Sequential References](#2-sequential-references)
6. [3. Template-Based References](#3-template-based-references)
7. [Getting Started](#getting-started)
8. [Model-Level Configuration](#model-level-configuration)
9. [Multi-Tenant Applications](#multi-tenant-applications)
10. [Collision Handling and Validation](#collision-handling-and-validation)
11. [Working With References](#working-with-references)
12. [Artisan Commands](#artisan-commands)
13. [Where Can Referenceable Be Used?](#where-can-referenceable-be-used)
14. [Built for Real Laravel Applications](#built-for-real-laravel-applications)
15. [Why I Built It](#why-i-built-it)
16. [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! 🚀

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

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

[About](https://www.msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleBifrost Turns One: AI Builds, MCP Server, and Automated Workflows for NativePHP](https://www.msaied.com/public/articles/bifrost-turns-one-ai-builds-mcp-server-and-automated-workflows-for-nativephp) [Next articlePayZephyr: One Payment API for Stripe, Paystack, and PayPal in Laravel](https://www.msaied.com/public/articles/payzephyr-one-payment-api-for-stripe-paystack-and-paypal-in-laravel)  

   On this page
-------------

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

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/740/cce86edc21eddcbdd2f2454fadaf9c70.png)  · 3 min read### The Pipeline Pattern in Laravel: Custom Pipelines Beyond Middleware

5 Oct 2026 ](https://www.msaied.com/public/articles/the-pipeline-pattern-in-laravel-custom-pipelines-beyond-middleware-1) [ ![](https://cdn.msaied.com/739/2d6897fdcdcf090613f96f72a64b8a78.png)  · 4 min read### MySQL Full-Text Search in Laravel: Indexes, Relevance Scoring, and Boolean Mode

4 Oct 2026 ](https://www.msaied.com/public/articles/mysql-full-text-search-in-laravel-indexes-relevance-scoring-and-boolean-mode) [ ![](https://cdn.msaied.com/738/073696a3fefe18bec825beec5ac658f5.png)  · 4 min read### Laravel Queue Rate-Limited Middleware: Throttling Jobs Without Losing Work

4 Oct 2026 ](https://www.msaied.com/public/articles/laravel-queue-rate-limited-middleware-throttling-jobs-without-losing-work) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/public/sitemap.xml)
