Appearance
Module Overview — Wallet Transaction Request / Commission
1. Scope
Feature này không nằm gọn trong một frontend module riêng. Nó cắt qua:
- frontend
ecommercecho request lifecycle và withdraw approval, - frontend
usercho wallet summary, withdraw history, employee commission ledger, - frontend
affiliatecho payout/commission mutate, - frontend
settingscho approver config và commission/payment config, - backend
wallet-apicho action/event engine, - backend
ecommerce-apicho upstream creator của commission và refund side effects, - Hasura metadata và migrations của DB
wallet.
Điểm cốt lõi cần nhớ:
transaction_requestlà engine trung tâm,transaction_request_userlà các leg sender/receiver,transactionchỉ được materialize khi request đi tớiS,- commission, refund, payout và topup đều chỉ là các family
behavior_idchạy trên cùng engine đó.
2. Bức tranh kiến trúc
text
FE surface (ecommerce / user / affiliate / settings)
-> GraphQL mutation / Hasura action
-> wallet.transaction_request + transaction_request_user
-> wallet-api action / event
-> DB trigger materialize transaction khi status = S
-> wallet balance / stats / ecommerce_transaction / notification side effects
Commission create path
-> ecommerce-api event/action
-> commission_util.AddCommission(...)
-> transaction_request status = S
-> DB insert transaction
-> wallet-api transaction_insert side effects
Refund / withdraw / payout path
-> FE insert transaction_request status = R
-> changeStatusTransaction
-> wallet-api transaction_request_update
-> success/cancel/reject side effects3. Frontend Surface
3.1 Write surfaces
| Surface | Module | Vai trò |
|---|---|---|
| Withdraw request list/create/detail | ecommerce | Tạo, sửa, duyệt, hủy request family refund/withdraw |
| Collaborator payout inline | user | Tạo withdraw request cho collaborator ngay trong customer detail |
| Affiliate withdraw form | affiliate | Tạo payout request cho affiliate/collaborator |
| Commission percent edit | affiliate | Thay đổi commission percent, gây side effect refund/commission |
| Promotion wallet / approver config | settings | Chỉ cấu hình visibility/gating, không trực tiếp ghi ledger |
3.2 Read surfaces
| Surface | Module | Vai trò |
|---|---|---|
| Wallet summary customer | user | Đọc wallet_stats, wallet_balance |
| Employee commission ledger | user | Đọc history wallet của staff |
| Commission report | report | Đọc aggregate/reporting model |
| Checkout/prepaid/product flows | ecommerce | Đọc wallet để quyết định payment source |
3.3 Permission map thực tế
| Case | Gate đang dùng |
|---|---|
| POS withdraw | refund_request_management + BranchPOS |
| IT/accounting withdraw management | fund_request_management |
| Affiliate payout edit | affiliate_management và không phải BranchPOS |
| Customer collaborator payout inline | Chủ yếu check isPlatformPos() ở UI host |
| Commission report | moduleId = report_management |
4. GraphQL / Action Map
| Operation | Loại | Surface chính | Mục đích |
|---|---|---|---|
walletBalances | Hasura action | user, affiliate, ecommerce | Đọc/cấp phát wallet rows theo user |
wallet_balance | SQL function query | ecommerce, affiliate, user | Đọc balance khả dụng theo wallet type |
wallet_stats | SQL function query | user, affiliate, ecommerce | Thống kê amount/inflow/outflow theo wallet |
RefundRequestCreate | mutation | ecommerce, user, affiliate | Tạo hoặc update transaction_request |
changeStatusTransaction | Hasura action | ecommerce | Approve / reject / cancel request |
GetOrderCommissionRefund | query/view | ecommerce | Đọc aggregate để tạo child refund_commission |
changeCustomerCommissionPercent | action | affiliate | Điều chỉnh commission percent, kéo theo refund/clawback |
5. Backend Flow Map
5.1 Request engine
| Lớp | File chính | Vai trò |
|---|---|---|
| Action | wallet-api/action/wallet.go | walletBalances: đọc balance facade và auto-create wallet |
| Action | wallet-api/action/change_status_transaction_refund.go | Gate transition approve/reject/cancel |
| Event | wallet-api/event/transaction_request_insert.go | Early sync HRM/refund log/order flags |
| Event | wallet-api/event/transaction_request_update.go | Sync refund log, notification, wallet refund, ecommerce side effects |
| Event | wallet-api/event/transaction_insert.go | Cập nhật before/after amount, ecommerce_transaction, ZNS |
| DB trigger | migration 1624088117982_initialization | Materialize transaction khi request thành công |
5.2 Upstream creator
| Source | File chính | Vai trò |
|---|---|---|
| Order confirm | ecommerce-api/action/order_confirm.go | Tạo transfer/withdraw path khi xác nhận order |
| Order item insert | ecommerce-api/event/order_item_insert.go | Nạp ví/topup từ prepaid order item |
| Invoice approved | ecommerce-api/event/invoice_insert_update.go | Tạo commission chuẩn |
| Referral / affiliate | ecommerce-api/action/handle_referral_customer.go | Temp commission, commission percent change, refund commission |
| Affiliate approval | ecommerce-api/action/affiliate_user_change_status.go | Chốt temp commission sang success |
6. Data Model Cốt Lõi
| Object | Vai trò |
|---|---|
wallet_type | Định nghĩa loại ví, currency, min_balance_capacity, flags default/promotion/disabled |
wallet | Số dư base theo (user_id, wallet_type_id) |
transaction_request | Request envelope: type, status, behavior, approver chain, reference |
transaction_request_user | Sender/receiver legs của request |
transaction | Ledger thực tế sau khi materialize |
wallet_balance / wallet_stats | Read models chính cho FE |
payment_gateway, payment_gateway_wallet_type, user_payment_gateway | 3 lớp cấu hình payment riêng nhau |
order_commission_refund | Read model aggregate commission/refund, không phải source-of-truth |
7. Semantic Rules Cần Nhớ
transaction_request.amountvàtransaction_request_user.amountlà requested amount;transaction.amountmới là ledger realized amount.reference_idkhông canonical; cùng field này đang bị dùng cho invoice, order, project task.walletBalanceskhông chỉ đọc dữ liệu, mà còn auto-create wallet row nếu chưa có.- Không phải mọi request chờ duyệt đều làm tăng
hold_amount; semantics hiện phụ thuộc status. - Commission create và commission clawback là hai nhánh khác nhau nhưng dùng chung
transaction_request.
8. Rủi ro / Findings
| ID | Mức | Finding |
|---|---|---|
| F-01 | P1 | FE không có wallet module riêng, nên permission và UX phân tán qua ecommerce, user, affiliate, settings. |
| F-02 | P1 | walletBalances là action đọc nhưng có side effect auto-create wallet, nên không thuần read-only. |
| F-03 | P1 | Request chờ duyệt R có dấu hiệu chưa được hold như business wording đang ngụ ý. |
| F-04 | P1 | transaction_request_user.amount và transaction.amount có thể drift nếu update request user sau khi bỏ trigger chống update. |
| F-05 | P1 | Commission idempotency hiện dựa trên checksum time-window, chưa phải business key ổn định. |
| F-06 | P2 | Nhiều FE surface đọc wallet/balance bằng query hoặc helper khác nhau, dễ dẫn tới không đồng nhất UX và validation. |