The Setup — What Happens When You Hit "Pay"?

Every time you pay via Google Pay, PhonePe, or Paytm, you enter a 4–6 digit UPI PIN. In your head, you probably think the app checks it. It does not. The app is completely blind to your PIN.

Here's the full cast of actors involved in every single UPI transaction:

UPI Transaction — Full Picture
  ┌────────────┐     ┌─────────────┐     ┌──────────────┐     ┌─────────────┐
  │  Your App  │────▶│  PSP Bank   │────▶│     NPCI     │────▶│ Issuer Bank │
  │ (GPay/PP)  │     │(Axis/HDFC   │     │  (the hub)   │     │ (your bank) │
  │            │     │  for GPay)  │     │              │     │             │
  └────────────┘     └─────────────┘     └──────────────┘     └─────────────┘
        │                                                              │
     You enter                                                  Decrypts &
     PIN here                                                   verifies PIN
     (app never                                                 against CBS
      sees it)
            
~1.5sAverage UPI transaction time
4Systems touched per payment
10RTGS settlement cycles / day
0Payment apps that can see your PIN

PIN Encryption — The HSM Magic

When you tap the UPI PIN keyboard on your phone and enter your digits, those keystrokes never go to Google Pay's servers. Instead, they go through the NPCI Common Library — a tamper-proof SDK embedded in every UPI app by NPCI mandate.

What is a PIN Block?

Your PIN doesn't travel as raw digits. It's packaged into a PIN Block using ISO 9564 Format 0. The format combines your PIN with the transaction details (like your account number) before encryption, so even replaying a captured encrypted PIN to a different account won't work.

// ISO 9564 Format 0 — simplified structure

PIN Block = Encrypt(
  PIN_Data XOR Account_Data,
  key = Public_Key_of_Issuer_Bank   // bank's HSM public key
)

// PIN_Data  → "0" + PIN_length + PIN_digits + padding
// Account_Data → "0000" + rightmost 12 digits of PAN

The HSM (Hardware Security Module)

Encryption happens using the Issuer Bank's public key, which is pre-loaded into the NPCI Common Library on your device. The corresponding private key lives only inside the bank's HSM — a tamper-proof hardware device. If someone tries to extract the private key physically, the HSM self-destructs it.

PIN Encryption on Device
  User types PIN
        │
        ▼
  ┌─────────────────────────────────────┐
  │         NPCI Common Library         │
  │  (runs in isolated secure enclave)  │
  │                                     │
  │  1. Accept PIN keystrokes           │
  │  2. Build PIN Block (ISO 9564-0)    │
  │  3. Encrypt with Bank's Public Key  │
  │  4. Clear raw PIN from memory       │
  └────────────────────┬────────────────┘
                       │  Encrypted PIN Block
                       ▼
              Goes into UPI API call
              (GPay server never sees raw PIN)
            
Key insight: The NPCI Common Library is a sealed SDK — Google Pay, PhonePe, and Paytm cannot modify it or intercept data flowing through it. NPCI audits it. This is why no payment app, no matter how malicious, can steal your UPI PIN.

NPCI Common Library in Practice

Every UPI-enabled app must integrate the NPCI UPI SDK. It renders its own secure PIN pad (the keyboard you type your PIN on), handles encryption, and delivers the opaque encrypted blob back to the app. The app treats it as a black box it cannot read.

NPCI — The Traffic Controller

The encrypted PIN block travels from your app → to the PSP Bank (Google Pay uses Axis Bank, PhonePe uses Yes Bank) → to NPCI.

NPCI is the National Payments Corporation of India. It built and owns UPI. Every UPI transaction must pass through NPCI's switching infrastructure, which does several things:

1
VPA Resolution
NPCI resolves the recipient's VPA (like user@okaxis) to a real bank account. It's essentially a DNS lookup for bank accounts — the VPA maps to an IFSC code + account number stored in NPCI's mapper.
2
Route to Issuer Bank
NPCI takes the encrypted PIN block and forwards the full transaction request to the Payer's Issuer Bank (where your money lives). It does NOT decrypt the PIN — it forwards the encrypted blob as-is.
3
Response Aggregation
NPCI collects the authorization response from the Issuer Bank, then coordinates the two-leg settlement (debit + credit), and sends the final success/failure back to the app.

Issuer Bank — The Actual Verifier

The Issuer Bank is the only entity that can verify your PIN. It's the only one holding the private key to decrypt the PIN block.

1
Decrypt PIN Block via HSM
The encrypted PIN block enters the bank's HSM. The HSM uses its private key to decrypt it. The raw PIN never exits the HSM — all comparison happens inside the hardware boundary.
2
Compare Against Stored PIN
Your PIN is stored in the bank's Core Banking System (CBS) as a one-way hash. The HSM hashes the decrypted PIN and compares the hashes. PIN matched → authorization proceeds. PIN wrong → transaction rejected, attempt counter incremented.
3
Balance & Fraud Check
The bank simultaneously checks: sufficient balance, daily transaction limit, fraud risk score (velocity checks, device fingerprint, etc.), and account status. All of this happens within the same authorization request.
4
Return Auth Response
The bank sends an authorization response code back to NPCI — either 00 (approved) or an error code. This triggers the SAGA pattern for the actual fund movement.
Why 3 wrong PIN attempts locks you out: Each failed attempt is logged in the CBS. At 3 failures, the bank flags the account for PIN lockout as a fraud prevention measure. The lockout is bank-side — no app can bypass it.

The SAGA Pattern — Debit, Credit, Rollback

Once the PIN is verified, the actual fund movement is orchestrated using the SAGA pattern — a distributed transactions pattern designed for systems where you can't use a traditional ACID transaction across multiple databases.

UPI involves at least two banks (payer's and payee's), each with their own databases. A two-phase commit across two separate banks' core banking systems is not feasible at UPI's scale. SAGA solves this.

D
Debit Leg
Step 1 — Debit the Payer's Account
NPCI sends a debit instruction to the Payer's Bank (your bank). The bank debits ₹X from your account and places the amount in an inter-bank settlement account (Nostro account at RBI). It returns a debit confirmation to NPCI.
C
Credit Leg
Step 2 — Credit the Payee's Account
Only after receiving the debit confirmation, NPCI sends a credit instruction to the Payee's Bank. The bank credits ₹X to the recipient's account. The payee sees "Payment Received" immediately.
R
Rollback
Auto Rollback — If Credit Fails
If the credit leg fails (payee account frozen, bank down, invalid account), NPCI triggers a compensating transaction — it reverses the debit by crediting the money back to the payer's account. This is the SAGA rollback. You get a "Payment Failed — Refund Initiated" message.
SAGA — Happy Path vs Rollback Path
  ── HAPPY PATH ──────────────────────────────────────────

  NPCI → Payer Bank: "Debit ₹500"
  Payer Bank → NPCI: "Debited ✓"
  NPCI → Payee Bank: "Credit ₹500"
  Payee Bank → NPCI: "Credited ✓"
  NPCI → App: "Transaction Successful ✓"

  ── ROLLBACK PATH ───────────────────────────────────────

  NPCI → Payer Bank: "Debit ₹500"
  Payer Bank → NPCI: "Debited ✓"
  NPCI → Payee Bank: "Credit ₹500"
  Payee Bank → NPCI: "FAILED ✗ (account frozen)"
  NPCI → Payer Bank: "Reverse debit — Credit ₹500 back"
  Payer Bank → NPCI: "Reversed ✓"
  NPCI → App: "Transaction Failed — Refund initiated"
            
Why the "pending" state exists: Between debit confirmation and credit completion, the transaction is in-flight. This is why your balance drops immediately but sometimes the recipient doesn't see the credit for a few seconds — the SAGA legs are executing sequentially.

No Money Actually Moves — It's All Ledger Entries

Here's the part that surprises most developers: physical money doesn't move between banks in real time. What moves are accounting entries.

How a Bank Account Actually Works

Your bank balance is a number in a database row — your account's ledger entry. When you "send" ₹500 via UPI:

-- Payer's Bank CBS (Core Banking System)
UPDATE accounts
SET balance = balance - 500,
    ledger_entry = 'DEBIT | TXN#xyz | ₹500 | NPCI'
WHERE account_id = 'payer_account';

-- Payee's Bank CBS
UPDATE accounts
SET balance = balance + 500,
    ledger_entry = 'CREDIT | TXN#xyz | ₹500 | NPCI'
WHERE account_id = 'payee_account';

-- No physical cash moved. Just two database updates.

The Inter-Bank IOU (Nostro/Vostro)

But wait — if both banks just update their own databases, how does the payer's bank actually "pay" the payee's bank? The answer is a Nostro/Vostro account system and RTGS settlement.

After the UPI transaction, the payer's bank owes the payee's bank ₹500. This debt is tracked as a net position. Throughout the day, thousands of such IOUs accumulate in both directions. Settlement (actual inter-bank money movement) happens in batch cycles — not per transaction.

Real-time doesn't mean real-time cash transfer. "Real-time" in UPI means real-time authorization and ledger update. The actual inter-bank fund transfer happens during the next settlement cycle.

RTGS Settlement — 10 Cycles a Day

At the end of each settlement cycle (there are 10 per business day), NPCI calculates the net position between all participating banks and instructs the Reserve Bank of India (RBI) to move funds between banks' accounts at RBI.

Net Settlement — End of Cycle
  Transactions during Cycle 1 (9am–10:30am):
  ─────────────────────────────────────────────
  HDFC → SBI:  ₹1,00,000  (500 transactions)
  SBI  → HDFC: ₹60,000    (300 transactions)
  ─────────────────────────────────────────────
  Net Position: HDFC owes SBI ₹40,000

  NPCI instructs RBI:
  → Debit HDFC's account at RBI: ₹40,000
  → Credit SBI's account at RBI: ₹40,000

  This single RTGS entry settles 800 UPI transactions.
            

Why Net Settlement?

Settling every UPI transaction individually via RTGS would be catastrophically expensive and slow. With 10 billion+ monthly UPI transactions, gross settlement is impossible. Net settlement aggregates thousands of opposing transfers and only settles the difference — massively reducing inter-bank fund movements.

10Settlement cycles per day
~1.5hPer cycle window
RBIFinal settlement authority
NetNetting reduces RTGS volume by ~90%
This is why refunds can take T+1 or T+2 days: A refund requires a new UPI transaction in the reverse direction, which itself goes through the settlement cycle. The money appears in your account once the payer's bank processes the credit leg and the next cycle settles.
Key Takeaways
  • Your UPI PIN is encrypted on your device using the Issuer Bank's public key, via the NPCI Common Library SDK. No payment app can see it.
  • The encrypted PIN block travels: App → PSP Bank → NPCI → Issuer Bank. Only the Issuer Bank's HSM can decrypt and verify it.
  • NPCI is the central switch — it resolves VPAs, routes transactions, coordinates the two-leg settlement, and handles rollbacks.
  • UPI uses the SAGA pattern: Debit Leg first, then Credit Leg. If the credit fails, a compensating transaction reverses the debit automatically.
  • No physical money moves during a UPI transaction — only ledger entries in each bank's Core Banking System are updated.
  • Inter-bank settlement happens via RTGS at RBI, in 10 batch cycles per day, using net positions — not per-transaction settlement.
  • Your "₹500 sent" is immediate in your ledger but the actual bank-to-bank fund transfer waits for the next RTGS cycle.