feat(payments): wallet screen with balances, benefits and storefront #218

Merged
developer merged 1 commits from feature/payments-wallet-ui into development 2026-07-08 16:44:06 +00:00
Owner

What

Add the Кошелёк (Wallet) section to the settings hub for durable players: the
context-visible chip balances, the active benefits (no-ads term / forever, hint count) and a
storefront of chip-priced values and money-priced chip packs. Guests have no wallet; the Google
Play build hides the money purchases behind a RuStore stub (spending earned chips still works); a
web purchase that would draw VK/Telegram chips warns the player first — the benefit becomes
web/native-only, by the store-compliance rules.

How

  • Catalog read (new): the storefront needed a way to list the catalog, so this adds a
    context-projected GET /api/v1/user/wallet/catalog — backend payments.Catalog + store loader,
    gateway wallet.catalog op + encoder, backendclient.Catalog, FBS Catalog / CatalogProduct
    / CatalogAtom, client decodeCatalog. A value carries a chip price shown in every context; a
    chip pack carries the money price for the running context's payment method (Votes / Stars /
    roubles).
  • Client leg for the existing wallet.get / wallet.buy ops (fetch + screen + mock seed).
  • Screen Wallet.svelte + a 'wallet' tab between Friends and About (guest-hidden,
    offline-disabled), logic extracted to lib/{wallet,distribution}.ts.

Notes / caveats

  • The storefront is empty on the test contour for now — no products exist until the admin
    catalog editor lands, and durable accounts hold 0 chips until payment intake / rewarded ads land.
    The populated UI is proven by the mock e2e; the empty states are what is reviewable on the
    contour today. (Interviewed and agreed: build the whole surface now, later work lights up its
    inputs.)
  • Chip-pack purchase is a disabled "Soon" placeholder — the money order flow arrives with
    payment intake; value spends work now via the existing spend path (a durable account has no chips
    yet, so a real spend returns insufficient-funds until funding exists).
  • The web-spend warning context is inferred client-side; the server enforces the real gate on every
    spend (fail-closed), so no wallet wire change was needed.
  • Google Play build detection is a build-time flag (VITE_GP_BUILD); off for web / VK / Telegram /
    RuStore.

Tests

  • Go unit (catalog context projection) + integration (/wallet/catalog over Postgres;
    soft-deleted excluded).
  • vitest (money/price formatting, spendable-segment selection, web-spend warning, GP flag) + codec
    decodeCatalog and gateway encodeCatalog round-trips.
  • Playwright mock e2e (render, tab placement, guest-hidden, GP stub, web-spend warning) on
    Chromium + WebKit.

Local full verification green: go build/vet ./backend/... ./gateway/..., gofmt -l clean,
backend unit + full integration suite, pnpm check (0 errors), 540 vitest, 12 e2e.

## What Add the **Кошелёк** (Wallet) section to the settings hub for durable players: the context-visible chip balances, the active benefits (no-ads term / forever, hint count) and a storefront of chip-priced values and money-priced chip packs. Guests have no wallet; the Google Play build hides the money purchases behind a RuStore stub (spending earned chips still works); a web purchase that would draw VK/Telegram chips warns the player first — the benefit becomes web/native-only, by the store-compliance rules. ## How - **Catalog read (new):** the storefront needed a way to *list* the catalog, so this adds a context-projected `GET /api/v1/user/wallet/catalog` — backend `payments.Catalog` + store loader, gateway `wallet.catalog` op + encoder, `backendclient.Catalog`, FBS `Catalog` / `CatalogProduct` / `CatalogAtom`, client `decodeCatalog`. A value carries a chip price shown in every context; a chip pack carries the money price for the running context's payment method (Votes / Stars / roubles). - **Client leg** for the existing `wallet.get` / `wallet.buy` ops (fetch + screen + mock seed). - **Screen** `Wallet.svelte` + a `'wallet'` tab between Friends and About (guest-hidden, offline-disabled), logic extracted to `lib/{wallet,distribution}.ts`. ## Notes / caveats - **The storefront is empty on the test contour for now** — no products exist until the admin catalog editor lands, and durable accounts hold 0 chips until payment intake / rewarded ads land. The populated UI is proven by the mock e2e; the empty states are what is reviewable on the contour today. (Interviewed and agreed: build the whole surface now, later work lights up its inputs.) - **Chip-pack purchase is a disabled "Soon" placeholder** — the money order flow arrives with payment intake; value spends work now via the existing spend path (a durable account has no chips yet, so a real spend returns insufficient-funds until funding exists). - The web-spend warning context is inferred client-side; the server enforces the real gate on every spend (fail-closed), so no wallet wire change was needed. - Google Play build detection is a build-time flag (`VITE_GP_BUILD`); off for web / VK / Telegram / RuStore. ## Tests - Go unit (catalog context projection) + integration (`/wallet/catalog` over Postgres; soft-deleted excluded). - vitest (money/price formatting, spendable-segment selection, web-spend warning, GP flag) + codec `decodeCatalog` and gateway `encodeCatalog` round-trips. - Playwright mock e2e (render, tab placement, guest-hidden, GP stub, web-spend warning) on Chromium + WebKit. Local full verification green: `go build/vet ./backend/... ./gateway/...`, `gofmt -l` clean, backend unit + full integration suite, `pnpm check` (0 errors), 540 vitest, 12 e2e.
developer added 1 commit 2026-07-08 10:37:33 +00:00
feat(payments): wallet screen with balances, benefits and storefront
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 19s
CI / ui (pull_request) Successful in 1m8s
CI / conformance (pull_request) Successful in 9s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m39s
4aa6174968
Add the "Кошелёк" section to the settings hub: context-visible chip
balances, active benefits (no-ads term/forever, hints) and a storefront of
chip-priced values and money-priced chip packs. Guests have no wallet; the
Google Play build hides the money purchases behind a RuStore stub; a web
purchase that would draw VK/Telegram chips warns first.

Add the catalog read path the storefront needs — a context-projected
GET /api/v1/user/wallet/catalog (payments service + store, gateway op
wallet.catalog, FBS Catalog/CatalogProduct/CatalogAtom, client decode) —
plus the client leg for the existing wallet.get/buy ops. Value spends reuse
the existing spend path; the chip-pack purchase (money order flow) arrives
with payment intake, so its action is a disabled placeholder for now.

Covered by Go unit (catalog projection) + integration (/wallet/catalog over
Postgres), vitest (formatting, spendable selection, web-spend warning, GP
flag, codec + gateway encode round-trips) and Playwright mock e2e (render,
guest-hidden, GP stub, warning) on Chromium + WebKit.
developer force-pushed feature/payments-wallet-ui from ce990a0c03 to 4aa6174968 2026-07-08 10:37:33 +00:00 Compare
owner approved these changes 2026-07-08 16:43:08 +00:00
developer merged commit 04976a64e8 into development 2026-07-08 16:44:06 +00:00
developer deleted branch feature/payments-wallet-ui 2026-07-08 16:44:06 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: developer/scrabble-game#218