QA
Intermediate LevelExpress JS

How do you implement Idempotency-Key middleware in Express to prevent duplicate payment processing?

❓ Interview Prompt: Explain API idempotency, Idempotency-Key header, caching completed response payloads in Redis, and preventing double-charge network retries.

When a client submits a payment request and experiences a network timeout before receiving the response, retrying the request can cause double charges.

Idempotency Middleware Pattern:

1
Client sends a unique 'Idempotency-Key: uuid-v4' HTTP header on POST requests.
2
Express checks Redis:
•
If key exists with status 'completed', return the cached response body immediately!
•
If key exists with status 'processing', return '409 Conflict' (request in progress).
•
If key is new, record key in Redis as 'processing', execute payment, cache final response in Redis for 24h, and return response!

Code Implementation Example

javascript
export const idempotencyMiddleware = async (req, res, next) => {
  const key = req.get('Idempotency-Key');
  if (!key) return next();

  const cached = await redis.get(`idempotency:${key}`);
  if (cached) {
    const { status, body } = JSON.parse(cached);
    return res.status(status).json(body); // Return cached response!
  }

  // Intercept res.json to cache response payload in Redis upon completion
  const originalJson = res.json.bind(res);
  res.json = (body) => {
    redis.set(`idempotency:${key}`, JSON.stringify({ status: res.statusCode, body }), 'EX', 86400);
    return originalJson(body);
  };
  next();
};
💡Redis-backed Idempotency-Key middleware for preventing duplicate transactions.
🎯 Interview Key Takeaway

Use Idempotency-Key headers and Redis caching to safely process network retries without duplicate side effects.

#Idempotency#Payments#Redis#Intermediate
Back to all Express JS Questions→

More Express JS Interview Questions

Beginner LevelExpress JS

What is Express.js and how does the middleware pipeline work?

Beginner LevelExpress JS

What is the difference between req.params, req.query, and req.body?

Beginner LevelExpress JS

How does express.Router() work for building modular route controllers?