Skip to content

Project · Backend Development

Project: a fast, reliable payments-status API

Projectexpert· about 7 hours· 6 steps

The brief

Paisa Pay's "check payment status" API gets hammered on salary day. Build the parts that keep it standing: a TTL cache, request de-duplication, a rate limiter that answers 429 with Retry-After, retries with exponential backoff, JSON logs that never leak secrets, and unit tests good enough to catch real GST bugs.

Why it matters

Fintech, e-commerce and ticketing backends in India face huge spikes (salary day, a Tatkal window, a Big Billion Days sale). Senior backend interviews ask how you would stop one slow dependency or one noisy client from taking everything down, and how you prove your code is right. This project is the hands-on answer.

Skills you practise

  • caching with a TTL
  • sharing in-flight promises
  • fixed-window rate limiting and 429
  • retries with exponential backoff
  • structured logging and redaction
  • unit tests that catch bugs
  • injecting clocks and sleep for testing

What you will have at the end

reliability.js: a tested cache, de-duplicated lookup, rate limiter, retry helper, safe logger and a GST test suite that catches real bugs.

How it is marked (rubric, 100 points)
Correct behaviourEvery check passes, including the time boundaries and failure cases.40
Production thinkingClocks and sleep are injected; only safe errors are retried; failures are not cached; secrets never logged.25
Test qualityYour GST tests cover normal, edge and error cases and would catch new bugs too.20
Can explainYou can explain cache stampedes, 429 with Retry-After, backoff and why logs must be redacted.15

0/6 steps done

Step 1 of 6

A cache with a time-to-live

createCache({ ttlMs, now }) returns get(key) (the value, or undefined when missing or expired), set(key, value) and stats() with hits, misses and size; expired entries are removed when read.

Payment status changes, so cached answers may only live a short time (a TTL, time to live). Store each value with its expiry time and check it on every read. Count hits and misses: the hit rate is the first number anyone asks about a cache.

The clock is passed in as now (a function returning milliseconds), with Date.now as the default. Tests can then move time forward instantly instead of waiting. Redis does the same job across many servers with SET key value PX 30000.

Run shows what your code prints. Check runs the step's tests. Ctrl+Enter checks too.