This is the decision screen — everything before it earns trust; everything after
it is commitment. The whole case study lives or dies here.
Screen header
Returns to Merchant — never loses the scan context
Som Tam Nua
Merchant name persists as a quiet anchor
Total hero — the one thing the eye lands on
You pay
฿420.00
THB
≈ $11.50 USD home estimate
◷ Rate locked 00:58
Local currency is the dominant number; home currency is secondary, never
the other way round. Rate-lock countdown is visible the entire time the screen is open.
Conditional — name-match confirmation pill
✓ CONFIRMED You confirmed the stall name matches the code
Only shown if the user came via the "Uncertain" edge state and confirmed the name. Reassures, doesn't nag.
Rate & fees — nothing hidden
Itemised, not summarised. Every line a card would bury is shown — including
the zeros, because "free" is the point.
Line
Detail
Amount
Exchange rate
mid-market · no markup
1 USD = 36.52 THB
Merchant amount
what the stall asked for
฿420.00 · ≈ $11.50
1QR fee
free under ฿1,000
฿0.00
Network fee
covered by 1QR
฿0.00
Total you pay
—
฿420.00 · ≈ $11.50
✓ You save ≈ $0.34 vs a typical card's ~3% conversion markup
Savings stated in home currency — the unit the traveler feels. Computed live from the locked rate.
Payment summary — what happens next
Paid to
Som Tam Nua ✓
Method
1QR balance · USD [tap to change]
Arrives
instantly, in THB
CTA restates the exact amount — never a bare "Pay". Tapping leads to Confirm (Hold-to-pay), not an instant charge.
Cancel any time before you confirm.
Currency hierarchy rule
The single most important visual decision on the screen.
Element
Currency
Weight
Hero amount
THB (local)
Dominant
Home estimate
USD
Secondary
CTA
THB
Dominant
Savings
USD
Supporting
Rate-lock states
State
Behaviour
Locked (>0:10)
Countdown ticks; Pay enabled
Expiring (≤0:10)
Countdown emphasised; still payable
Expired (0:00)
Re-fetch rate, re-confirm new total before Pay
The rate the user agreed to is the rate they pay — or they re-agree. No silent re-pricing.
Shown only when savings > 0; else hide the strip (never show "$0.00 saved").
Screen states to cover in Figma
Free tier (฿0 fees) — default, shown here
Paid tier (≥฿1,000) — fee line populated
Rate expired — re-confirm variant
Method = card vs balance vs baht pocket
Name-match pill present / absent
Wireframe notes — for Figma reference
The hero total is the anchor of the whole product — local currency dominant, home currency always beside it,
never the reverse. If a viewer remembers one frame from 1QR, it should be this one.
Every fee is a visible line, including the ฿0.00 ones — the "free" lines are persuasion, not clutter. Fees
are never folded into the exchange rate.
Rate-lock countdown is present from the moment the screen opens and governs whether Pay is live — an expired
lock forces a re-confirm of the new total before any charge.
The savings strip is computed live against the locked rate and stated in the home currency; it is hidden
entirely when savings are zero or negative rather than shown as "$0.00".
Primary CTA always restates the exact amount ("Pay ฿420.00 →") — there is no bare "Pay" button on this
surface by design.
Pay does not charge — it advances to Confirm (Hold-to-pay), preserving one deliberate commitment moment.
"Cancel any time before you confirm" sits under the CTA as a standing escape hatch; the back arrow returns to
Merchant without losing scan context.
Method row is a live control — tapping it opens the payment-method picker (balance · baht pocket · card) and
re-runs the fee + savings math on return.
The name-match confirmation pill is conditional — only present when the user passed through the "Uncertain /
mismatched name" edge state and confirmed; it reassures without nagging everyone else.
Core principle enforced by this screen: the true cost is fully visible before the money moves — no DCC, no
surprise conversion, no fine print.