Skip to content
BACK TO ARTICLES
JAN 20267 min readBackend

Building Reliable Payment APIs

SV

Sujal Vijayvargiya

SDE-1

Idempotency, state machines, and reconciliation — the three pillars of payment API reliability I've learned building high-scale transaction flows at Juspay.

#Payments#APIs#Distributed Systems#Reliability

Idempotency Is Non-Negotiable

Networks fail. Clients retry. In payment systems, processing the same transaction twice is a catastrophic failure. Every mutation endpoint that touches financial state must require an idempotency key and store a deduplicated result before executing downstream side effects.

Use atomic database upserts or Redis SET NX locks — not application-level checks — to guarantee safety under concurrent retries.

typescript
// Every payment mutation requires an idempotency key
async function processPayment(key: string, tx: Transaction): Promise<Receipt> {
  const existing = await db.idempotencyStore.findOne(key);
  if (existing) return existing.result;  // Deduplicated

  const lock = await redis.setNX(`lock:${key}`, 1, 30_000);
  if (!lock) throw new ConcurrentRequestError();

  try {
    const receipt = await executePayment(tx);
    await db.idempotencyStore.upsert(key, receipt);
    return receipt;
  } finally {
    await redis.del(`lock:${key}`);
  }
}

State Machines Over Boolean Flags

Payment transactions have complex lifecycles: pending, authorized, captured, refunded, failed. Representing this with boolean flags (isAuthorized, isCaptured, isRefunded) creates exponentially many invalid combinations.

Explicit state machines with transition guards eliminate impossible states entirely. When I redesigned Juspay's pre-auth platform with formal state transitions, a whole class of race condition bugs simply ceased to exist.

Build Reconciliation From Day One

External payment gateways are eventual systems. Your internal state and the gateway's state will diverge — guaranteed. Build reconciliation jobs from the start, not as an afterthought. For our mandate migration work, reconciliation wasn't a monitoring concern — it was the core product guarantee.

— END OF TRANSMISSION —

RETURN TO BLOG