PHPackages                             codenaline/laravel-idempotency - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. codenaline/laravel-idempotency

ActiveLibrary[Caching](/categories/caching)

codenaline/laravel-idempotency
==============================

Laravel middleware and drivers for handling Idempotency Keys (Cache, Database, Redis).

068PHPCI passing

Since Dec 26Pushed 6mo agoCompare

[ Source](https://github.com/codenaline/laravel-idempotency)[ Packagist](https://packagist.org/packages/codenaline/laravel-idempotency)[ RSS](/packages/codenaline-laravel-idempotency/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

📦 Laravel Idempotency
=====================

[](#-laravel-idempotency)

A professional Laravel package for handling **Idempotency Keys**.
It ensures that duplicate requests (like hitting the payment button twice) are processed only once, safely returning the same response.

---

🚀 Features
----------

[](#-features)

- Support for `Idempotency-Key` header in requests (customizable)
- Three storage drivers:
    - Redis → blazing fast, ideal for high‑traffic environments
    - Database → persistent and easy to monitor
    - Cache → simple and flexible using Laravel’s cache system
- TTL (time‑to‑live) support for automatic expiration
- Artisan command to purge expired keys (Database driver only)
- Full Pest test coverage (Feature, Unit, Command tests)

---

📥 Installation
--------------

[](#-installation)

```
composer require codenaline/laravel-idempotency
```

---

⚙️ Configuration
----------------

[](#️-configuration)

Publish the config file:

```
php artisan vendor:publish --tag=idempotency-config
```

### Example `config/idempotency.php`

[](#example-configidempotencyphp)

```
return [

    'header' => env('IDEMPOTENCY_HEADER', 'Idempotency-Key'),

    'default' => env('IDEMPOTENCY_DRIVER', 'redis'),

    'drivers' => [

        'redis' => [
            'connection' => env('IDEMPOTENCY_REDIS_CONNECTION', 'default'),
            'ttl' => env('IDEMPOTENCY_TTL', 60),
        ],

        'database' => [
            'connection' => env('IDEMPOTENCY_DB_CONNECTION', config('database.default')),
            'table' => env('IDEMPOTENCY_DB_TABLE', 'idempotency_keys'),
            'ttl' => env('IDEMPOTENCY_TTL', 60),
        ],

        'cache' => [
            'store' => env('IDEMPOTENCY_CACHE_STORE'),
            'ttl' => env('IDEMPOTENCY_TTL', 60),
        ],
    ],
];
```

---

🔑 Custom Header
---------------

[](#-custom-header)

By default, the package looks for the header:

```
Idempotency-Key: abc123
```

You can change the header name in `config/idempotency.php`:

```
'header' => env('IDEMPOTENCY_HEADER', 'Idempotency-Key'),
```

For example, if you want to use `X-Request-Id` instead:

```
IDEMPOTENCY_HEADER=X-Request-Id
```

Then your requests should include:

```
POST /payments
X-Request-Id: abc123
```

---

🛠️ Usage
--------

[](#️-usage)

Add the middleware to your routes:

Attach the middleware to your routes to enable idempotency:

```
Route::post('/payments', [PaymentController::class, 'store'])
    ->middleware('idempotency');
```

By default, the middleware will use the **TTL** value defined in your configuration file (`config/idempotency.php`).

You can override the TTL for a specific route by passing it as a parameter to the middleware:

```
Route::post('/payments', [PaymentController::class, 'store'])
    ->middleware('idempotency:120'); // TTL = 120 seconds
```

This allows you to fine‑tune expiration times depending on the sensitivity of each endpoint.
For example:

- Short TTL (e.g. 30 seconds) for lightweight requests.
- Longer TTL (e.g. 600 seconds) for heavy operations like payment processing.

Each request must include the idempotency header.
If the same key is reused, the previous response will be returned instead of re‑processing.

---

🧹 Purging Expired Keys
----------------------

[](#-purging-expired-keys)

- Redis / Cache drivers → no purge needed, TTL is handled automatically by the storage engine.
- Database driver → purge is required to clean up expired rows.

Run the Artisan command manually:

```
php artisan idempotency:purge
```

Schedule it in `app/Console/Kernel.php`:

```
protected function schedule(Schedule $schedule): void
{
    // Run every hour
    $schedule->command('idempotency:purge')->hourly();

    // Or daily
    // $schedule->command('idempotency:purge')->daily();
}
```

---

🧪 Testing
---------

[](#-testing)

This package ships with full Pest tests:

- Feature tests for middleware flow
- Unit tests for each driver (Cache, Database, Redis)
- Command tests for purging expired keys (Database driver only)

---

📌 Summary
---------

[](#-summary)

- Prevents duplicate request execution
- Supports three drivers: Redis, Database, Cache
- TTL expiration included
- Header name customizable (`Idempotency-Key` by default)
- Purge command only needed for Database driver, can be scheduled in the Laravel Kernel
- Ready for production with full test coverage

---

🤝 Contributing
--------------

[](#-contributing)

Pull requests are welcome! Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

👨🏻‍💻 Credits
------------

[](#‍-credits)

- [Mahdi Rezaei](https://github.com/mahdirezaei-dev)

📄 License
---------

[](#-license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

20

—

LowBetter than 13% of packages

Maintenance47

Moderate activity, may be stable

Popularity12

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity13

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/228968206?v=4)[codenaline](/maintainers/codenaline)[@codenaline](https://github.com/codenaline)

---

Top Contributors

[![mahdirezaei-dev](https://avatars.githubusercontent.com/u/53124341?v=4)](https://github.com/mahdirezaei-dev "mahdirezaei-dev (19 commits)")

---

Tags

laravelphp

### Embed Badge

![Health badge](/badges/codenaline-laravel-idempotency/health.svg)

```
[![Health](https://phpackages.com/badges/codenaline-laravel-idempotency/health.svg)](https://phpackages.com/packages/codenaline-laravel-idempotency)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
