Work / Aakalan / Wiki / Surfaces
settle-pay
Surfacecanonicalverified 2026-09-23
SURFACE.MOBILE.SETTLE.PAYSummary
You owe them, and their UPI ID is on file.
Raw wireframe
- .context/designs/mobile/settle/pay.html
Why it is drawn this way
The whole flow is on one screen, always reached with the person already chosen. The "Settle up" LIST screen that used to sit in front of this is gone: it listed the same people with the same balances, and you tapped it in order to reach a list. The balance hero's Settle button had already been removed for exactly that reason; this one outlived it.
The two directions are two different screens sharing a frame, and the difference is not a sign flip. When you owe there is a payment to make; when you are owed there is nothing to pay — only something to record. See settle-receive.
An empty amount box means "all of it". That is the overwhelmingly common case, so it must not require typing the number already on screen. The "Full" chip this replaced had a selected state that meant "the field is empty"; partial payment is an edit, not a mode.
The UPI app chips are gone. GPay / PhonePe / Paytm / BHIM, where any
already opens the system chooser, which lists the apps actually installed —
choosing a named one you do not have just fails. See upi-cannot-pay-a-number.
"Opened" is the only thing observable. iOS gives no callback and Android's is unreliable, so the user is asked whether it went through, never assumed. The prompt says what saying yes does.
The payee falls back to the first on file rather than to null. methodId is
seeded once, on a first render where the person can still be undefined; when the
payee list landed after that, no row rendered as selected and the Pay button was
disabled forever — a primary CTA that swallowed every tap with nothing on screen
explaining why.
Cash / bank is inline, defaulting to cash. It was an Alert fired on the primary button, so every settlement cost a modal and an extra tap — for a label that renders as one line of small grey text in the ledger.
"Where this comes from" is gone. A per-group breakdown of the balance is a read, not a decision, and person is one tap away.
Its empty state is reachable without anything being wrong, by two routes — the balance was settled on another device, or you arrived from a GROUP member row and the person nets to zero across groups. The copy says which rather than repeating "square".
Related
Sources
- src/app/settle/[id].tsx
- src/services/upi.ts
Every project of mine is written down like this.
Read the résumé