PhonePe Frontend Interview
Payments-app frontend interviews typically combine JS fundamentals, UI coding, and design-system thinking. Composite guidance for SDE2-shaped loops.
- interview-experience
- phonepe
Composite guidance based on publicly shared candidate reports and common hiring patterns for frontend / UI roles on consumer payments apps. Processes vary by role, level (SDE1 vs SDE2-shaped), and year. Always confirm with your recruiter. Not a personal diary, not affiliated with PhonePe.
PhonePe frontend interviews are easy to lose on a boring UPI miss: the user taps Pay, the request leaves, the app loses the foreground, and on return the screen is a spinner with no memory of the txn id. Consumer payments loops score reliability and empty states as hard as they score a JS filter. Design-system thinking means you reuse patterns (amount, PIN, status) instead of inventing a new modal each time.
SDE2-shaped packets often start with a JavaScript fundamentals round (sometimes a polyfill or async util), then UI coding, then a deeper design or HM conversation. Teams differ. Ask.
Key takeaways
- A JS filter is common: language, polyfills, async, not only DSA trivia.
- Pay flows need txn identity, resume-after-background, and honest pending/fail states.
- Empty wallets and failed UPI are the product, not edge cases.
- Speak in design-system pieces: amount field, PIN, status timeline.
UPI-speed UI and a JS filter round
| Stage | Focus | Format |
|---|---|---|
| Recruiter | Level, org (consumer, merchant, platform) | Call |
| JS filter | Language, polyfill, async util | Shared editor / OA |
| UI coding | Pay slice, list, components | Timed |
| Design / web | App shell, design system, perf | Conversation |
| HM | Ownership, production stories | Call |
Some candidates see two JS rounds. Some see a take-home. SDE2 usually means you must explain tradeoffs, not only pass hidden tests.
The JS filter
Treat it as a language interview. Typical families of prompts (not claimed PhonePe items):
- Implement
map/filter/reduce/Promise.allas a standalone function, then discuss prototype mutation - Debounce, throttle, once, memoize
- Flatten, deep clone, event emitter
- Output questions: event loop,
this, closures
Walk the method in How to approach polyfill questions. Worked builtins live under array map polyfill, array reduce polyfill, Promise.all polyfill, call/apply/bind. Dry-run practice: JavaScript output-based questions.
Name sparse-array holes and thenables. map skips holes. Promise.all rejects on the first rejection and keeps fulfillment order. Those are spec facts, not style opinions.
function once(fn) {
let called = false;
let result;
return function wrapped(...args) {
if (called) return result;
called = true;
result = fn.apply(this, args);
return result;
};
}
A once wrapper is the same instinct as a Pay button that must not fire twice, with the caveat that server idempotency still matters. See once function.
UPI-speed UI
Consumer pay is a short critical path: enter amount → pick payee → authenticate (PIN / system sheet) → pending → success or fail. Seconds matter. So does resume.
Talk through:
- Identity: client generates a clientRequestId; server returns a txn id. Persist both before you navigate away.
- In-flight: disable amount edits. Show pending that is not a blocking mystery spinner with no copy.
- Backgrounding: on visibility return, fetch status by id. Do not replay Pay.
- Failure: insufficient balance, user declined, timeout, unknown. Each has a next action.
- Empty states: no payees, no network, wallet zero, KYC blocked.
Machine coding that trains the same muscles: OTP input boxes, toast notification system, offline status indicator, multi-step wizard, polling metrics dashboard (status polling). Framework: machine coding interview framework.
Network: fetch, AbortController, retry with jitter only when the operation is idempotent. XSS on any HTML status payload: XSS.
Design-system thinking
Payments apps repeat a small set of primitives. In a design round, name them and reuse:
| Primitive | Hard parts |
|---|---|
| Amount | keypad, decimals, large type, locale |
| Payee row | avatar, VPA, last-paid |
| PIN / OTP | one logical field, paste, masked |
| Status timeline | pending vs terminal, polling |
| Bottom sheet | focus trap, dismiss, a11y |
That is design a design system at app scale, not a new color palette. Accessibility on PIN and amount is non-negotiable: accessible forms, keyboard checklist.
For mid+ design prompts (home, transaction history, split-pay), use design a news feed structure: constraints, tree, data, failure, perf. Transaction history is a virtualized list with day headers, not a map of 5,000 DOM rows.
DSA and level
SDE2-shaped loops may still include medium DSA in JS: hashes, strings, trees, LRU. Prep Two Sum, LRU Cache, Valid Parentheses, Binary Search. If the recruiter says “pure JS + UI,” bias the calendar toward polyfills and MC, but do not skip patterns.
Senior signal is production stories: a payment bug you diagnosed, a design-system migration, a performance budget. See senior frontend interview signals.
Footguns
- Re-tapping Pay because pending UI was unclear
- Storing PIN in component state longer than the submit
innerHTMLfor bank error text- Empty-state sarcasm instead of a next action
- Polyfill that walks holes wrong, or mutates
Array.prototypewithout saying so
Preparation plan (6 weeks)
- Weeks 1–2: Polyfills + event loop teach-back. One standalone function per day.
- Weeks 3–4: Pay-flow MC (amount + status). One history list with virtualization.
- Week 5: Design outline of home + pay + history. a11y pass.
- Week 6: Mocks including a JS filter and a “what if the sheet is dismissed” drill.
Out loud: “I treat Pay as an idempotent command with a client request id I persist before the network returns. The JS round is a standalone polyfill with holes and thenables named first. UI work reuses amount, PIN, and status primitives instead of a new modal. Empty and pending states have a next action, including resume after background.”