Skip to main content

Tasks — Player → Shop/Cashier (Phase 3)

Spec: player-to-shop-cashier · Mockup: Redemptions tab

Phụ thuộc: Phase 2 deposit (schema + shop cash-transactions API nền); Cashier redeem + approval (Cashier spec).


Tóm tắt nghiệp vụ

Khi Shop redeem credit của Player, Shop trả lại Player một khoản tiền mặt tương ứng tại quầy.

Player yêu cầu rút credit
→ Shop/Cashier xác nhận
→ Trừ credit Player, cộng credit Shop (CDN wallet)
→ Shop trả tiền mặt cho Player
→ Ghi sổ cash (Cash Out) + báo cáo

Hai số liệu bắt buộc khi thao tác:

TrườngÝ nghĩaVí dụ
Số credit redeemCredit trừ khỏi ví Player30 credits
Số tiền mặt trả PlayerCash Shop đưa trực tiếp cho Player$30.00

V1: thường 1:1 (30 credits → $30.00), nhưng Shop nhập cả hai để hệ thống ghi nhận rõ ràng credit đã thu hồi và cash đã chi. Ledger và báo cáo dùng số tiền mặt trả Player cho Cash Out — không suy diễn từ credit.

Phạm vi V1: Chỉ redemption. Auto-settled khi completed; pending approval không tạo cash tx.


Ai làm gì

Vai tròHành động
PlayerYêu cầu rút; có mặt tại quầy
Shop ManagerNhập credit redeem + tiền mặt trả Player; xác nhận redeem từ Shop portal
CashierNhập credit redeem + tiền mặt trả Player; trả cash sau completed (hoặc sau Manager approve)
Hệ thốngDebit player wallet, credit shop wallet, ghi cash_transactions, cập nhật shift Cash Out

Hai kênh thực hiện

KênhAPIGhi chú
Shop portalPOST /shop/players/:id/credits (action: deduct)Không bắt buộc shift
Cashier portalPOST /cashier/players/:id/redeemActive shift; cash only

Cả hai kênh đều phải thu credit redeemcash paid; sau khi wallet transfer thành công → tạo cash_transactions flow shop_player_redemption.


Phase 1 — Schema

#TaskGhi chú
1.1Flow shop_player_redemptionNếu chưa ship cùng Phase 2 migration
1.2metadata.approvalId optionalLink approval record (Cashier path)
1.3Doc schema-cash-transactionscredit_amountcash_received khi cần

Phase 2 — Backend biz (redemption only)

#TaskGhi chú
2.1createCounterRedemptionCashTransactionseller=player, buyer=shop
2.2Payload: credit_amount + cash_paid (cash_received)Cả hai bắt buộc, > 0
2.3expected_cash = cash_paidSố tiền mặt Shop chi
2.4Hook sau _adjustCreditsDeductChỉ khi wallet transfer completed
2.5Không hook từ pending_approvalChỉ sau approve + transfer
2.6Shop portal action: deductValidate + truyền cash_paid vào ledger
2.7Cashier redeemCreditsBody thêm cash_paid; cashDelta = −cash_paid
2.8Wire sau cashierRedemptionApprovalBizService approveApproval dùng cùng cash_paid đã lưu
2.9Idempotency theo reqIdTránh duplicate cash tx
2.10Unit testsHappy path; insufficient balance; pending→approve; cash ≠ credit (nếu cho phép)

File chính: cashTransactionBizService.js, shopPlayerBizService.js, cashierTransactionBizService.js, cashierRedemptionApprovalBizService.js

Ledger (cash_transactions):

FieldValue
flowshop_player_redemption
sellerplayer / player uuid
buyershop / shop uuid
credit_amountSố credit redeem
expected_cash / cash_receivedSố tiền mặt trả Player
statuspaid_full (auto khi completed)

Links: payment_transaction_id, wallet txs, cashier_transaction_id, shift_id, metadata.approvalId.


Phase 3 — Shop portal API (redemption filter)

#TaskGhi chú
3.1GET /api/shop/cash-transactions?flow=shop_player_redemptionList redemptions
3.2Detail hiện credit + cash paid + approval context
3.3Summary: Cash Out (SUM cash_received), pending approval countAggregate toàn bộ filter, không chỉ page
3.4Export CSVCột credit redeem + cash paid

Mở rộng shopCashSettlementController — hiện chỉ filter shop_player_deposit.


Phase 4 — Shop portal UI

#TaskGhi chú
4.1Tab Payable — RedemptionsMockup phase2 redeem tab
4.2Modal redeem Player: 2 ô nhập — credit redeem + cash trả PlayerPre-fill cash = credit (1:1); Shop sửa nếu cần
4.3Review step hiện cả credit và cash trước confirm
4.4Summary card Cash Out (today / filter)Từ ledger cash_received
4.5Bảng: player, credits redeemed, cash paid, cashier/actor, statusSettled / Pending approval
4.6Badge Pending approval vs Settled
4.7Combined dashboard: Cash In (P2) + Cash Out (P3) = NetOptional sau cả hai tab

Phase 5 — Cashier / Shift

#TaskGhi chú
5.1Cashier redeem form: credit + cash paidGiống Shop portal
5.2Redemption completed → shift Cash Out = cash_paidKhông dùng credit amount cho cashDelta
5.3Pending approval: cashDelta = 0Chưa trả tiền
5.4Cashier tx list hiện CTX-* sau settleRead-only; hiện cash paid
5.5Integration test Expected Closing CashCash Out khớp tổng redemption

Phase 6 — Báo cáo

#TaskGhi chú
6.1Shop portal Redemptions tab summaryCash Out aggregate
6.2Export CSV redemptioncredit_amount, cash_received, player, date
6.3Shift reconciliation reportCash Out từ redemption dùng cash_paid
6.4Admin / Shop cash-transaction detailView-only; link payment + wallet txs

Phase 7 — QA (redemption)

#ScenarioExpected
7.1Shop redeem 30 credits, trả $30 cashcash tx: credit=30, cash_received=30; wallet −30/+30
7.2Shop redeem 30 credits, trả $28 cash (nếu cho phép)cash tx cash_received=28; shift cashDelta −28
7.3Cashier redeem pending approvalNo cash tx; cashDelta = 0
7.4Approve → completecash tx created once với cash_paid đã lưu
7.5Insufficient player balance400; no cash tx
7.6Shop manual deduct thiếu cash_paid400 validation
7.7Idempotent retry cùng reqIdMột cash tx duy nhất

Thứ tự triển khai

Phase 2 deposit done
→ Schema redemption (1)
→ Biz hook + cash_paid payload (2)
→ Shop API redemption filter (3)
→ UI: modal 2 ô + tab Redemptions (4)
→ Cashier cash_paid + shift (5)
→ Báo cáo (6)
→ QA (7)

Hiện trạng (baseline)

Thành phầnTrạng thái
Wallet transfer player → shop
Cashier redeem + approval + cashDelta (1 field)✅ — cần thêm cash_paid
Shop portal manual deduct (1 field)✅ — cần thêm cash_paid
cash_transactions flow shop_player_redemption
Shop portal redemption ledger + báo cáo Cash Out