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
Player✅Player belonging to shop
Credits / amount✅V1: 1:1 — 50 credits = $50 cash
Method✅ (fixed)cash
Shift / Cashier / Device✅ (system)Auto-attached from session + active shift

Shop portal (manual add)​

FieldRequiredDescription
Player✅Player belonging to shop
Credits✅Positive number, > 0
payment_method✅cash | card | bank transfer
action✅add

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 wallet — effectiveLevel 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