Appearance
Shared Rules — Wallet Transaction Request / Commission
1. Thuật ngữ chuẩn
| Thuật ngữ | Nghĩa trong code hiện tại | Ghi chú |
|---|---|---|
| Transaction Request | wallet.transaction_request | Request envelope trung tâm cho nạp/chuyển/rút/commission/refund |
| Transaction Request User | wallet.transaction_request_user | Sender/receiver legs của request |
| Transaction | wallet.transaction | Ledger thực tế sau khi request thành công |
| Behavior | wallet_master_data | Phân loại nghiệp vụ: transaction_commission, refund_order, refund_commission... |
| Hold Amount | Tổng amount sender đang bị giữ theo rule của DB function | Không đồng nghĩa mọi request chưa xong đều bị giữ |
| Available Balance | wallet.amount - hold_amount - min_balance_capacity | Mức khả dụng thực tế để tạo request mới |
| Commission | Request family cộng tiền vào ví COMMISSION hoặc VND_PROMOTION | Thường tự sinh từ ecommerce-api |
| Commission Refund / Clawback | Request family thu hồi commission | Có thể là child request hoặc request sender mới |
2. Type Matrix
| Type | Ý nghĩa | Family phổ biến |
|---|---|---|
D | Deposit | commission, topup ví, cashback |
T | Transfer | commission clawback, điều chuyển giữa ví/người dùng |
W | Withdraw | refund cho khách, payout, collaborator withdraw |
3. Status Matrix
| Status | Ý nghĩa |
|---|---|
R | Requesting |
P | Processing |
S | Success |
F | Failure |
C | Canceled |
Reject | Rejected |
Điểm đáng chú ý:
- Family refund/withdraw hiện chạy nhiều ở
R -> S/C/Reject. - Business wording trong docs cũ hay nói “pending” chung, nhưng DB function
hold_amountchỉ cộngP. RejectvàCcùng tồn tại, nên test case phải phân biệt “bị từ chối” với “người tạo hủy”.
4. Behavior Matrix
| Behavior | Family | Engine | Mô tả ngắn |
|---|---|---|---|
transaction_commission | Commission | wallet.transaction_request | Cộng commission chuẩn khi invoice approved |
refund_order | Refund | wallet.transaction_request | Hoàn order dịch vụ |
refund_order_cosmetic | Refund | wallet.transaction_request | Hoàn order mỹ phẩm |
refund_topup | Refund | wallet.transaction_request | Hoàn topup/prepaid liên quan |
refund_collaborator | Payout / refund | wallet.transaction_request | Chi/hoàn tiền liên quan collaborator |
refund_commission | Commission clawback | wallet.transaction_request | Thu hồi commission đã trả |
event_bonus | Bonus | wallet.transaction_request | Thưởng sự kiện / campaign nếu cấu hình |
5. Invariants quan trọng
SR-001: transaction_request là source-of-truth workflow
- Approver chain, status, behavior, order/reference đều nằm ở đây.
transactionchỉ là hệ quả sau khi request tớiS.- Vì vậy mọi phân tích workflow phải bắt đầu từ
transaction_request, không bắt đầu từ ledger.
SR-002: transaction_request_user.amount khác với transaction.amount
transaction_request_user.amount: requested amount theo leg sender/receiver.transaction.amount: amount đã materialize vào ledger.
Hệ quả:
- reporting hoặc reconciliation không được trộn hai lớp này như nhau,
- update request user sau khi request đã được materialize có thể làm lệch ledger.
SR-003: reference_id không phải khóa canonical
Trong code hiện tại, reference_id có thể gắn với:
- invoice,
- order,
- project task.
Ngoài ra nhiều flow còn có order_id riêng.
Hệ quả:
- luôn ghi rõ join bằng
reference_idhayorder_id, - không được dùng
reference_idnhư business key duy nhất.
SR-004: walletBalances không thuần query
Action này:
- ép
user_idvề caller nếu không phải admin, - lọc wallet type theo flags,
- tự tạo wallet missing rows.
Hệ quả:
- test read-path phải chấp nhận side effect tạo row,
- mọi mô tả “chỉ query balance” là chưa đúng.
SR-005: Hold amount là invariant ở DB function, không phải invariant toàn hệ thống
- DB function hiện chỉ cộng sender legs của request
T/Wcó statusP. - Một số flow approval lại dùng
R -> S/C/Reject.
Hệ quả:
- business expectation “request đang chờ duyệt thì bị giữ tiền” không luôn đúng,
- QA cần tách test theo status thật, không theo wording màn hình.
6. Boundary Checklist
Khi phân tích bug hoặc change request trong vùng này, luôn hỏi:
- Đây là request family nào: commission create, payout, refund, hay clawback?
- Nguồn tạo request nằm ở FE mutation trực tiếp hay ở
ecommerce-apihelper/util? - Read path đang dùng
wallet_balance,wallet_statshaywalletBalances? - Status thực tế của case này có đi qua
Pkhông? - Reporting đang dựa vào ledger thật hay read-model/view như
order_commission_refund?
7. Rủi ro / Findings
| ID | Finding |
|---|---|
| SR-F01 | Vocabulary “wallet”, “transaction”, “request”, “commission” đang bị dùng lẫn giữa FE page, GraphQL và DB table. |
| SR-F02 | Hold semantics hiện khác wording trong business docs cũ, nên rất dễ viết acceptance criteria sai. |
| SR-F03 | Một số read model như order_commission_refund hoặc wallet_stats rất hữu ích, nhưng không phải source-of-truth workflow. |