feat(registry): Steam: link an account to a Steam id and buy through ISteamMicroTxn #18

Merged
kblack0610 merged 2 commits from feat/registry-steam into main 2026-11-04 16:27:53 +00:00
Owner

Premium phase 7, registry side. The Steamworks.NET client waits for phase 2 (playground Entitlements).

What it adds (registry/steam.go, README "Steam purchases"):

  • POST /api/v1/steam/link: checks a Web API auth ticket with ISteamUserAuth/AuthenticateUserTicket and stores the Steam id in account_identities (provider steam). One Steam id per account, one account per Steam id.
  • POST /api/v1/steam/purchases: InitTxn at the catalog price, usersession=client. Then POST .../{orderId}/finalize (FinalizeTxn, which grants with source steam, receipt = order id) and GET .../{orderId} (QueryTxn). When a finalize fails, QueryTxn decides what happens.
  • Refunds: Steam sends no event, so an hourly GetReport pass from a stored cursor revokes Refunded and Chargedback orders and grants any Succeeded order the client never finalized. POST /api/v1/admin/steam/reconcile runs the pass on demand.
  • Every Steam route answers 503 until STEAM_WEB_API_KEY and STEAM_APPS are set. STEAM_ENVIRONMENT defaults to sandbox (ISteamMicroTxnSandbox).
  • Migration 0007: steam_orders and steam_report_cursors, plus a unique (account_id, provider) index on account_identities, which replaces the plain account index.
  • Removed duplication: gamePairs now does the EDGEGAP_APPS and STEAM_APPS parsing, and sellableItem holds the active, owned and free checks for both Square checkout and Steam.

assumed: one STEAM_APPS game=appid map instead of a single app id, because the registry serves several games.
assumed: prices go to Steam in USD cents and Steam converts them for the player.
assumed: PartialRefund keeps the item (an order holds one item). Only full refunds and chargebacks revoke.
assumed: the ticket identity is STEAM_TICKET_IDENTITY, default bnb-registry. The client must pass the same string.

Checks: go test ./... on the merged head: 116 tests pass, 6 of them new Steam tests running against a fake Steam Web API (off and 503, boot config, link conflicts, init/finalize/query grant and revoke, init failure, reconcile cursor and refund). This repo has no PR CI, so the local run is the gate.

Not done: a real sandbox purchase. That needs the human Steamworks setup (README steps 1-5).

https://claude.ai/code/session_01BALUC1f7pXD9Fh4WLuymTG

Premium phase 7, registry side. The Steamworks.NET client waits for phase 2 (playground Entitlements). What it adds (registry/steam.go, README "Steam purchases"): - `POST /api/v1/steam/link`: checks a Web API auth ticket with `ISteamUserAuth/AuthenticateUserTicket` and stores the Steam id in `account_identities` (provider `steam`). One Steam id per account, one account per Steam id. - `POST /api/v1/steam/purchases`: `InitTxn` at the catalog price, `usersession=client`. Then `POST .../{orderId}/finalize` (`FinalizeTxn`, which grants with source `steam`, receipt = order id) and `GET .../{orderId}` (`QueryTxn`). When a finalize fails, `QueryTxn` decides what happens. - Refunds: Steam sends no event, so an hourly `GetReport` pass from a stored cursor revokes `Refunded` and `Chargedback` orders and grants any `Succeeded` order the client never finalized. `POST /api/v1/admin/steam/reconcile` runs the pass on demand. - Every Steam route answers 503 until `STEAM_WEB_API_KEY` and `STEAM_APPS` are set. `STEAM_ENVIRONMENT` defaults to sandbox (`ISteamMicroTxnSandbox`). - Migration 0007: `steam_orders` and `steam_report_cursors`, plus a unique `(account_id, provider)` index on `account_identities`, which replaces the plain account index. - Removed duplication: `gamePairs` now does the `EDGEGAP_APPS` and `STEAM_APPS` parsing, and `sellableItem` holds the active, owned and free checks for both Square checkout and Steam. assumed: one `STEAM_APPS` game=appid map instead of a single app id, because the registry serves several games. assumed: prices go to Steam in USD cents and Steam converts them for the player. assumed: `PartialRefund` keeps the item (an order holds one item). Only full refunds and chargebacks revoke. assumed: the ticket identity is `STEAM_TICKET_IDENTITY`, default `bnb-registry`. The client must pass the same string. Checks: `go test ./...` on the merged head: 116 tests pass, 6 of them new Steam tests running against a fake Steam Web API (off and 503, boot config, link conflicts, init/finalize/query grant and revoke, init failure, reconcile cursor and refund). This repo has no PR CI, so the local run is the gate. Not done: a real sandbox purchase. That needs the human Steamworks setup (README steps 1-5). https://claude.ai/code/session_01BALUC1f7pXD9Fh4WLuymTG
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kblack0610/bnb-game-servers!18
No description provided.