apps/api/refunds/refundsService.ts +84 −9
async function processRefund(req: RefundRequest) {
- const existing = await ledger.find(req.id);
- if (existing) return existing;
+ const key = req.headers['idempotency-key'];
+ if (!key) throw new HttpError(400, 'missing idempotency-key');
+ const cached = await redis.get(`refund:${key}`);
+ if (cached) return JSON.parse(cached);
const tx = await ledger.reverse(req.txnId);
+ await redis.set(`refund:${key}`, JSON.stringify(tx), 'EX', 86400);
return tx;
}
apps/api/refunds/refundsService.test.ts +38
+ it('returns cached response on retry with same key', async () => {
+ const first = await svc.processRefund({ ... headers: { 'idempotency-key': 'a' } });
+ const second = await svc.processRefund({ ... headers: { 'idempotency-key': 'a' } });
+ expect(second).toEqual(first);