Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

06 — Screen Specifications (Payments)

The largest document: precise specs for each payments screen. All tokens referenced from 00-shared/02_Design_Tokens.md; components from 00-shared/03.


S1 — Payments list

Layout

  • AppBar: title "Payments", actions: receipts icon, search icon.
  • Body: search field (sticky), filter chips row (All / Completed / Pending / Processing / Failed / Refunded / Partially refunded — client-side), list, load-more footer.
  • FAB: AppFAB.extended "Record payment" — hides on scroll down.
  • Padding: 16 phone / 24 tablet+. Section gap 24. Card gap 12.

Row composition (AppListTile 72 dp)

  • Leading: gateway icon (offline = cash icon) in primaryContainer circle.
  • Title: transactionReference (mono, titleSmall).
  • Subtitle: payerName + date (bodySmall, onSurfaceVariant).
  • Trailing: amount (titleMedium, tabular figures) + status AppBadge.
  • On tap: ripple + push S2.

Status badge mapping

StatusBadge color (role)Icon
completedsuccesscheck_circle
pending / processinginfo (primaryContainer)schedule
failederrorcancel
refunded / partially_refundedtertiarycurrency_rupee/replay

States

  • Loading: 8 AppSkeleton rows; shimmer m-slow.
  • Empty: AppEmptyState (icon payments, "No payments yet", CTA "Record payment").
  • Error: AppErrorState code-aware (403 → permission empty-state; 5xx → generic + requestId + Retry).
  • Offline: AppOfflineBanner; cached last-good list (client cache 5 min).
  • Pagination: footer "Load more" → spinner → next page; "End of list" bodySmall when total reached. Server returns {data,total} — client computes hasNext locally.

A11y

  • Row: single semantics node "Payment TXN-…, amount, status".
  • Chips: Semantics(selected:); results count live region.
  • Contrast per 00-shared/09; touch targets ≥ 48.

Animations

  • New row entrance: fade+rise stagger 40 ms.
  • Status chip change: AnimatedSwitcher 150 ms.

S2 — Payment detail

Layout

  • Hero header card: amount headlineMedium tabular; status badge; transaction reference mono bodySmall with copy icon.
  • Info cards (each AppCard e-1, padding 16, gap 12):
    • Payer: name, email, payerId.
    • Invoice: link (route to invoice), status, paidAmount/totalAmount progress bar (linear, m-base).
    • Gateway: gateway, gatewayTransactionId, gatewayResponse.
    • Money: amount, fee, refundedAmount, currency.
    • Timeline: createdAt, updatedAt (from BaseSchema).
  • Actions row (primary/secondary):
    • Receipt (FilledButton.tonal) → S6.
    • Refund (OutlinedButton destructive) → S4 (visible iff payments.refund + status completed).
    • Reconcile (OutlinedButton) → S5 (visible iff PENDING/PROCESSING + payments.reconcile).

States

  • Loading: skeleton cards.
  • 404: AppErrorState "Payment not found" (no retry; back offered).
  • Conflict after action: banner with server message.

A11y

  • Copy button: tooltip + semantics "Copy transaction reference"; announce "Copied".
  • Amounts: Semantics numeric value.

S3 — New payment form (full-screen)

Layout

  • AppBar title "Record payment", close/back.
  • Form column (gap 16): amount*, currency, gateway*, gatewayTransactionId, invoice (searchable AppDropdown), payerName, payerEmail, payerId, description, submit FilledButton fullWidth (48 dp).
  • Keyboard: resizeToAvoidBottomInset; scroll into view on focus; amount → next, submit on last field (action "Done").
  • Safe areas: bottom padding = nav/safe area + 16.

Components & tokens

  • Amount: AppTextField keyboard TextInputType.numberWithOptions(decimal:true), formatter decimal 2 places, error "Enter a valid amount (min 0)".
  • Gateway: AppDropdown from PaymentGateway enum — icons per method.
  • Invoice: optional; selecting prefills amount (editable after) + payerName from invoice payer when present.
  • Submit: loading swaps label → spinner; fields disabled while pending; double-tap blocked.

States

  • Validation: server 400 details mapped to fields; generic banner for others.
  • Success: navigate-inline to success view: payment + receipt cards + actions (View receipt, Done → S1 refreshed).
  • Failure: banner AppBanner error + Retry; form values preserved.

Dark/light: token-based only.

A11y

  • Labels visible; autofill hints (name, email).
  • Error announcement via live region; focus first invalid field.

S4 — Refund sheet

  • AppBottomSheet with drag handle; title "Refund payment".
  • Refundable amount info row (bodyMedium).
  • Amount field (default full refundable, min 0.01, max refundable).
  • Reason AppTextField (required, 3–200 chars).
  • Submit FilledButton destructive (error colors) loading state; Cancel TextButton.
  • Server 409 messages → inline error under amount / banner.
  • Confirm semantics: Semantics(button, label "Confirm refund of amount").
  • Sheet dismiss: back gesture/ESC = cancel; no discard warning (non-destructive form).

S5 — Reconcile sheet

  • Title "Reconcile payment".
  • Outcome AppRadio group: Success / Failed / Pending.
  • Gateway response text field (optional).
  • Submit → PATCH; result status reflected on S2; errors → banner + retry.

S6 — Receipt view

  • Receipt card (centered, max width 480, e-1, padding 24):
    • Header: "Receipt" + receiptNumber mono; school/org name (tenant branding) (planned).
    • Body: amount large, fee, currency, payment method; payer name/email; description; payment reference; invoice id.
    • Footer: issuedAt date (locale), paymentId.
  • Actions: Share (forward-looking); Copy receipt number.
  • Print: (planned) reports module PDF.
  • A11y: receipt is a Semantics summary; amounts spoken fully.

S7 — Receipts list

  • Mirrors S1; rows: receiptNumber, amount, date, payerName; tap → S6.
  • Pagination same {data,total} handling.

Global interaction details

  • Haptics: success lightImpact; error mediumImpact; refund confirm heavyImpact.
  • Hover (desktop): row tint surfaceContainerHigh; destructive hover errorContainer.
  • Focus order: search → chips → list → FAB; visible primary ring.
  • Hero: invoice → payment amount cross-fade (no shared element needed).
  • Reduced motion: all m-instant fades.