boone-studios / laravel-idempotency
Stripe-style Idempotency-Key middleware for multi-tenant Laravel APIs.
Package info
github.com/boone-studios/laravel-idempotency
pkg:composer/boone-studios/laravel-idempotency
Requires
- php: ^8.2
- illuminate/cache: ^12.0|^13.0
- illuminate/database: ^12.0|^13.0
- illuminate/http: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
Requires (Dev)
- orchestra/testbench: ^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
This package is auto-updated.
Last update: 2026-07-11 21:59:20 UTC
README
Stripe-style Idempotency-Key middleware for multi-tenant Laravel APIs.
- Requires an idempotency header on mutating requests
- Cache-locks concurrent retries
- Replays the stored response on matching payload
- Returns
409 Conflictwhen the same key is reused with a different body - Prunes expired records via Eloquent's
Prunable
Requirements
- PHP 8.2+
- Laravel 12 or 13
Installation
composer require boone-studios/laravel-idempotency
php artisan vendor:publish --tag=idempotency-config php artisan vendor:publish --tag=idempotency-migrations php artisan migrate
Configuration
scope_resolver must be configured before you use this middleware. There is
no default implementation — the package ships as null and will throw a
RuntimeException at request time (with a message pointing back to this
config key) if you register the idempotency middleware on a route without
setting it first.
Implement BooneStudios\Idempotency\Contracts\ResolvesIdempotencyScope and set it in config/idempotency.php:
'scope_resolver' => App\Services\TenantContext::class, 'scope_column' => 'tenant_id', // or vendor_id, organization_id, …
Register the middleware:
Route::middleware('idempotency')->post('/orders', …);
Only apply the idempotency middleware to routes where a scope/tenant is
always resolvable (e.g. authenticated, tenant-scoped endpoints). Routes that
legitimately have no tenant yet (e.g. a signup endpoint) should not use this
middleware — resolution failure is treated as a configuration error, not a
"no tenant" case.
License
MIT © Boone Studios, LLC