Skip to main content

Shop/Cashier → Player (Counter Deposit)

Phase 2 in the Cash Settlement chain — after Phase 1 hierarchy (Admin → SA → Agent → Shop).

Player pays cash at the counter → Shop/Cashier confirms → credits added to player wallet, shop CDN wallet debited accordingly.

Player pays cash → Cashier/Shop confirms → credits to Player → reconciliation ledger (Cash In)

Redemption flow (Player exchanges credits for cash) is a separate Phase 3: Player → Shop/Cashier.

Mockup: Phase 2 — Deposits tab · Cashier spec: Cashier Management spec


Position in the system

flowchart LR
subgraph P1["Phase 1"]
AG[Agent] --> SH[Shop CDN wallet]
end
subgraph P2["Phase 2"]
SH --> P[Player wallet]
end
subgraph P3["Phase 3"]
P --> SH2[Shop — redemption]
end
P1 --> P2
P2 -.-> P3

Shop must have sufficient credit in CDN wallet (from Phase 1 Agent→Shop) before issuing credits to Player.

Unlike Phase 1 hierarchy: counter deposit is auto-settled on complete — cash and credits move simultaneously; V1 has no temporary receivables.


Who does what

RoleAction
PlayerPays cash at counter; receives credits after Cashier/Shop confirms
CashierFind player, enter amount/credits, confirm deposit (cash only, within active shift)
Shop ManagerMay manually add credit from Shop portal (cash / card / bank transfer)
SystemDebits shop CDN wallet, credits player wallet, writes audit, updates shift Cash In

Two execution channels

ChannelRoleConditionsAPI
Cashier portalCounter cashierActive shift required; cash onlyPOST /cashier/players/:id/deposit
Shop portalShop ManagerShift not requiredPOST /shop/players/:id/credits (action: add)

Cashier path writes cashier_transactions (shift reconciliation). Shop Manager path writes shop_action_logs. Both do not yet write cash_transactions ledger (Phase 2 target).


Required information

Cashier portal (V1)

FieldRequiredDescription
PlayerPlayer belonging to shop
Credits / amountV1: 1:1 — 50 credits = $50 cash
Method✅ (fixed)cash
Shift / Cashier / Device✅ (system)Auto-attached from session + active shift

Shop portal (manual add)

FieldRequiredDescription
PlayerPlayer belonging to shop
CreditsPositive number, > 0
payment_methodcash | card | bank transfer
actionadd

Amount & margin formulas

V1 counter deposit: 1 credit = $1 USD (face value for Player).

MetricFormula
Cash received (expected)credit_amount
Shop CDN costcredit_amount × shop.costRate (snapshot)
Shop gross margincredit_amount × (1 − shop.costRate) — reporting metadata

Example: cost rate 0.80, deposit 50 credits:

ItemValue
Cash received$50.00
Shop CDN cost$40.00
Gross margin$10.00
Shop CDN wallet−50
Player wallet+50

Counter deposit always debits the current shop walleteffectiveLevel is reporting snapshot only.


Business rules

  1. Player belongs to shop, not banned.
  2. Shop has sufficient credit in CDN wallet.
  3. Cashier: active shift required; no OTP.
  4. After complete: no edit / cancel / reverse.
  5. cashDelta = +amount (cash) → Cash In in shift.

Proposed ledger (cash_transactions)

FieldValue
flowshop_player_deposit
sellershop / shop uuid
buyerplayer / player uuid
expected_cash= credit_amount (1:1 V1)
statuspaid_full (auto)

Links: payment_transaction_id, wallet txs, cashier_transaction_id (cashier path), shift_id.


Current backend

Cashier: cashierTransactionBizService.depositCredits
→ playerCreditPort.transferCreditsAtCounter (deposit)
→ shopPlayerBizService._adjustCreditsAdd
→ walletTransferService (shop → player)
→ PaymentTransaction (provider: shop_player_cash)
→ CashierTransaction (type: deposit_credits)

Shop: shopPlayerBizService.adjustPlayerCredits (action: add)
→ same _adjustCreditsAdd (not via shift)

API

Existing

MethodEndpointBody
POST/api/cashier/players/:id/deposit{ "amount": number }
POST/api/shop/players/:id/credits{ "action": "add", "amount": N, "payment_method": "cash" }

Phase 2 target

MethodEndpointDescription
GET/api/shop/cash-transactions?flow=shop_player_depositList deposits
GET/api/shop/cash-transactions/:idDetail
GET/api/shop/cash-transactions/exportCSV

Proposed UI (Shop portal)

Tab Receivable — Deposits on mockup phase2-counter:

  • Summary: Counter Cash In, Gross margin (today)
  • Table: player, cashier, credits, cash received, margin, receipt
  • Detail view-only

Cashier portal: transactions live in Active Shift — no separate ledger needed for V1.


Current status

ComponentStatus
Wallet transfer shop → player
payment_transactions + cashier_transactions
cash_transactions flow shop_player_deposit
Shop portal deposit ledger

Tasks: tasks-shop-cashier-to-player