top of page
Search

Design a real-time transaction processing system for Google Pay.

  • Writer: Gigs Logic
    Gigs Logic
  • Jul 27, 2025
  • 4 min read

Updated: Aug 13, 2025

(Think of UPI, wallets and merchants.)



Before we jump into designing a transaction system, let’s quickly understand what idempotency means.


🔹 What is Idempotency?

Duplicate request? Idempotency means:

Bhai, already ho gaya, chill maar.

Imagine this:

  • You hit “Pay ₹100”

  • App shows network error

  • You hit “Pay” again

Without idempotency → ₹200 gets debited.With it → System says:

“Same txn ID hai boss, already done. Chill.”Result? One clean payment, no double debits.
Now lets come to its components:

Flow Diagram:


🔹 API Gateway—The Waiter of Your System

API Gateway is your app’s front guy. Instead of mobile app talking to 10 services, it just talks to one.

Socho ek restaurant hai 🍽️:

You:

Butter chicken, naan, ek lassi.”

Waiter (API Gateway):

  • Samajh gaya

  • Kitchen ke alag-alag chefs ko instructions di

  • Sab laake plate mein serve kar diya


That’s exactly how API Gateway works.



🔹 Transaction Service—Payment Ka Control Room 🚦

This guy is the mastermind.

  • It doesn’t directly move money.

  • doesn’t write to DBs,

  • but it does create a transaction ID

and orchestrates everything else.


Socho:

  • Alice pays ₹100 to Bob

  • Transaction Service says:


    “ID banao, balance check karo, fraud dekh lo, idempotency thikh hai? Toh bhai, chalo aage 🚀”.”

Payment wallet se ho ya UPI se, it just says:

Plug a new method, implement karo, kaam ho gaya 💥”

Aaj UPI, kal Crypto—no code change.


🔐 Alright, but where do we store these transaction IDs safely and quickly?

PostgreSQL? SQL? Redis?


👉 Use Redis.

Why?

  • In-memory hai which means super fast

  • High load mein chhoti-chhoti checks chahiye

  • Redis is fast, light, and perfect for quick checks.


Har kaam DB se karwana zaroori nahi — Redis hai apna chhota bhai: tez, sasta, aur har waqt standby.”

But wait—Redis keys expire (5 min TTL)? Toh, we will have a two-layer check:

  • Check Redis

  • Not there? Check Postgres

  • Found? Reuse old txn result


🔹 Wallet Service—Balance Ka Boss

Handles top-up, debit, and refund.


Flow:

  • The user pays ₹100

  • Transaction → Wallet: debit ₹100

  • Wallet → Kafka: “Debit Alice, Credit Merchant.” (Kafka here to log events)

  • Ledger logs it (think of Ledger as book of records)

  • Wallet confirms and updates Redis


Note: Wallet never blindly updates balance. Ledger confirmation is a must.


Wallet Service bina Ledger ki confirmation ke kuch nahi karta—boss ka order chahiye har baar.



🔹 UPI Service—Ek Callback Aur Game Palat Gaya 🎬💥

“Yahan callback ka scene filmy hai boss — ek late response, aur pura game ulta.”


UPI collect/pay ke liye bank se baat karta hai.

Flow:

  • Transaction triggers UPI collect

  • The bank takes 3–10 sec to reply

  • Success? Ledger gets: debit Alice, credit Bob

  • Transaction marked as SUCCESS

Also handles timeouts, retries, and duplicate callbacks


💥 But What If It Fails?—Callback and Side Effects 🎭

UPI is async by nature, and callback timing decides everything.Kabhi pehle timeout ho jaata hai, aur baad mein callback aata hai.Matlab: “Interval ke baad hero entry, par tab tak climax khatam!”

Here are 2 common real-life fail scenes the system must handle:


1. Callback Never Came (Timeout)


Problem: Bank never responds

Effect: Transaction stuck in “Pending”

Fix: Use background reconciliation jobs

“Bank chup… system wait karta raha… transaction bas latak gaya 😵”


🕰️ 2. Success Callback After Retry


Problem: You retried assuming failure, but original success callback arrives later

Effect: Double debit or wrong status

Fix: Always check txn status before acting

“Retry ke baad asli callback aaya, lekin system already move on kar chuka tha 💔”



🔹 Merchant Service—Fee Lagao, Route Batao, Paisa Sambhalo💼

This service is the backend ka dukandar — quietly managing merchant money, fees, and where the payment should go.

  • Maps QR to wallet/UPI

  • Decides routing (wallet vs UPI)

  • Applies platform fee (e.g. 2%)


Example:

  • ₹100 paid to merchant

  • The merchant gets ₹98, and the Platform gets ₹2

  • Ledger logs both

Later, ₹98 goes to the merchant bank via settlement.



🔹 Ledger Service—Jahan Sab Likha Jaata Hai 📒

The single source of financial truth. Every money movement is logged here.


You can visualise this as a double-entry system: one debit and one credit, always in sync.

Kafka helps:

Transaction Service publishes to ledger-events topic✅ Ledger reads the event and writes two entries✅ Wallet optionally listens and updates balance

Even if services crash → Kafka ensures no loss.


🧩 Transaction Flow With Kafka-Backed Ledger

Let’s walk through an example:


User A pays ₹100 to User B


🔁 Step-by-Step


  1. Transaction Service publishes a ledger event:


➤ This message is published to a Kafka topic: ledger-events


2. Ledger Service subscribes to ledger-events topic

  • It reads the event

  • Validates and processes it

  • Writes two records into the ledger database:

  • Debit for Alice

  • Credit for Bob


3. Wallet Service (optional) subscribes too:

  • Updates real-time balances in Redis or DB

  • Sends notifications, etc.

🔐 Why Kafka?

  • Events are stored even if services crash

  • Can handle thousands of transactions/sec

  • You can replay ledger events to rebuild state


🔄 Retry & Fault Tolerance

  • If writing to DB fails (e.g., the ledger DB is down), Kafka will keep retrying until it succeeds.

  • The ledger consumer can track offsets—so no event is lost or processed twice.

Visual Example:

🔹 Settlement Service — Real Paisa Transfer Yahan Se

“Yahan asli paisa move hota hai—not just system ke numbers, but actual INR 💸”


Every hour/night:

  • Service picks all merchant credits

  • Net payout calculated (after fees)

  • ₹50,000 credit? → ₹49,500 gets transferred

  • Bank API (NEFT/IMPS/RTGS) used

  • Ledger updated → marked as settled

Retry later or alert ops — but never mark as settled until bank confirms. 💼


⚠️ What If Settlement Fails?

Let’s say the NEFT request failed due to invalid IFSC.

The service should:

  • Mark that payout as FAILED

  • Retry after some interval (or alert ops team)

  • Never mark the ledger entries as “settled” until bank confirms success



This was a high-level breakdown of how real-time transaction systems like Google Pay work under the hood. Want me to dive into any specific part deeper? Drop a comment below!

🚀 Follow for more such backend breakdowns!

For references:




 
 
 

Comments


Wireless Computer Accessories
  • Instagram
© 2025 by Gigs Logic . All rights reserved.
Want to connect?
Get a callback and get things sorted
bottom of page