Package-level declarations
Types
Android realization of PaymentHost. Providers cast the opaque host to this to reach the ComponentActivity (some SDKs — Razorpay, Cashfree — require an Activity to open their sheet) and to register ActivityResult contracts (Stripe, UPI intent) without owning the registry themselves.
Feature a gateway supports — drives capability-filtered lookups and Lab badges.
The app's view of the server's Stripe Connect payout onboarding rail (roadmap #11) — mirrors PayoutBackend's shape: onboard/completeOnboarding do the server round-trips, status polls server-authoritative state. Implemented in core:network against core:protocol DTOs.
Normalized failure taxonomy — every provider maps its own SDK error zoo into these.
Catalog metadata for a gateway — everything the Lab home needs without touching the impl.
Whether a provider can be exercised end-to-end in this showcase.
Thrown by WalletLedgerPort.debit when the wallet balance can't cover the requested amount.
A server-created order the client is about to pay. The client never sets the amount — it sends a catalog item id and the backend resolves the price (the trust boundary this whole app exists to demonstrate). This is what the backend returns from POST /orders.
Where the app finds its payments backend server.
The app's view of the server. Implemented in core:network (Ktor) against the core:protocol DTOs; consumed by the orchestrator in domain terms only, so the orchestrator never sees a DTO or an HTTP concern. This is the seam that lets the tested core run against a fake backend.
The single contract every payment provider implements. Deliberately tiny and platform-agnostic: the messy, Activity-callback-era SDK reality is confined to each provider's androidMain impl and bridged back into a coroutine by PaymentHost.
The collected set of gateways available in the app. Each provider:* module contributes one PaymentGateway into DI; the app assembles them here. Features depend only on this registry, so adding provider N+1 touches no existing feature code.
Platform handle a PaymentGateway needs to launch its SDK/UI. Deliberately opaque in commonMain — it carries no platform types, so the contract stays multiplatform. On Android the concrete host (see AndroidPaymentHost in androidMain) owns the ComponentActivity + ActivityResult plumbing and bridges the SDK's callback back into the suspending PaymentGateway.pay call.
Thrown by PaymentGateway.prepare when the order/session could not be created.
The terminal (or near-terminal) outcome of a payment attempt, as reported by the client SDK.
A point-in-time snapshot of server-side payment state.
Server-authoritative payment state — the domain mirror of PaymentStatusDto.
One observable step in a payment's lifecycle, emitted by the orchestrator as a stream. The Lab screen renders these as a live timeline (order created → launching → client result → verifying → terminal), each carrying its RedactedPayload so the user sees the actual data at every hop.
The app's view of the server's Transfers/payout rail (roadmap #4) — mirrors PaymentBackend's shape: initiate does the server round-trip, status polls the server-authoritative state a mock settlement webhook updates. Implemented in core:network against core:protocol DTOs.
Payout lifecycle — the domain mirror of PayoutStatusDto.
A durable record of one payment attempt.
The process-death insurance policy. A pending row is written here before the SDK launches, so if the app is killed mid-payment (OEM battery kill, user swipe, low memory during the bank's 3DS WebView) the orchestrator can, on next cold start, find unresolved payments and reconcile them against the server. Implemented by core:data (Room).
Why a payment is not yet terminal.
Opaque, provider-specific data produced by PaymentGateway.prepare and handed to PaymentGateway.pay. Each provider stuffs its own session material into params: Razorpay → order_id + key_id; Cashfree → payment_session_id; Stripe → client_secret; UPI intent → the constructed upi:// reference fields.
A key/value snapshot of an SDK request or response that has already passed the redaction allowlist — safe to render in the Lab timeline and to log. Constructing one asserts "these fields are non-secret". Secrets and PII never reach this type; the redactor drops them upstream.
Turns an arbitrary provider request/response map into a RedactedPayload safe to render and log.
A saved instrument as the app ever sees it — masked, never the raw card token.
The scripted outcome a SimulatedPayment run should settle to.
Stands in for a real SDK round-trip when a gateway has no live sandbox credentials (GatewayStatus.MOCK_MODE). A short suspend delay mimics the SDK hop; the outcome is scripted (not random) so the Lab timeline is deterministic and every mock-mode gateway can be demoed end-to-end with zero credentials.
Which leg of a split payment a PaymentStep.LegSettled belongs to.
A Tier-4 "stub/docs-only" catalog entry: real enough to appear in the Lab list with an honest GatewayStatus.COMING_SOON badge and a web-researched doc, but with no working integration behind it (no backend adapter, no real or mock SDK call). pay always fails — nothing should ever actually invoke it in normal use since the UI badges it as not-yet-available, but the contract still has to return something rather than throw if it somehow is.
Everything a Tier-4 catalog-only entry needs: identity + the research-backed blurb/docs link.
The app's view of the server's Stripe Customer + vault rail (roadmap #7) — mirrors PayoutBackend's shape: save/list/charge each do a server round-trip against core:protocol DTOs. Implemented in core:network.
GET /wallet/{accountId}/balance response.
POST /wallet/{accountId}/debit request — the ledger "pay" movement, carries an idempotency key.
Slim port onto the wallet's double-entry ledger, used ONLY by the orchestrator (see PaymentOrchestrator.paySplit) for the split-payment wallet leg's compensating credit. Deliberately separate from PaymentGateway — refund/compensation is an orchestration concern (per the split-payment design), not part of the gateway contract every provider implements.
POST /wallet/{accountId}/refund request — the ledger "refund" movement (a credit back).