Tutorials Courses Interview Prep (100 Q&A) AI Tools (50) Developer Tools (50) Tracks Pricing Plans Blog & Articles Contact Us
Laravel Advanced & Architecture 5-8 Years (Senior) Hard Production Scenario

How do you implement Idempotent API endpoints in Laravel to prevent duplicate charges upon client network retries?

Real-World Scenario / Incident Description

A mobile client with poor connectivity sent 3 consecutive `POST /api/v1/payments` requests with the same card payload when the network timed out, causing the customer to be billed 3 times.

371 views • Updated 1 month ago

Idempotency Key Middleware Implementation

class EnsureIdempotency
{
    public function handle(Request $request, Closure $next): Response
    {
        $idempotencyKey = $request->header('Idempotency-Key');
        if (! $idempotencyKey) {
            return response()->json(['error' => 'Idempotency-Key header is required'], 400);
        }

        $cacheKey = "idempotency:{$request->user()->id}:{$idempotencyKey}";
        $lock = Cache::lock("lock:{$cacheKey}", 15);

        if (! $lock->get()) {
            return response()->json(['error' => 'Concurrent request in progress'], 409);
        }

        if ($cachedResponse = Cache::get($cacheKey)) {
            $lock->release();
            return response()->json($cachedResponse['data'], $cachedResponse['status']);
        }

        $response = $next($request);

        if ($response->isSuccessful()) {
            Cache::put($cacheKey, [
                'data' => json_decode($response->getContent(), true),
                'status' => $response->getStatusCode(),
            ], now()->addHours(24));
        }

        $lock->release();
        return $response;
    }
}
Related Concepts: #API Design #Idempotency #Payments #Security #Resilience