Appearance
Đơn hàng (Orders) — Business Rules
Tổng quan
orders trong ecommerce thực tế gồm 3 dòng order chính và 3 lớp side-domain đi kèm:
- service order
- product/cosmetic order
- prepaid order
- invoice / debt / commission
- refund / withdraw / commission payout
- negative payment
Điểm quan trọng: ba loại order không đi cùng một payment pipeline.
Ba loại order
| Loại | Đặc trưng |
|---|---|
| Service order | Gắn order item dịch vụ, appointment, project task, commission theo service |
| Product order | Bán mỹ phẩm/hàng hóa, gắn inventory/delivery, payment flow FE còn khá đặc thù |
| Prepaid order | Bán thẻ/gói trả trước, có rule riêng về commission và giá trị nạp ví |
Trạng thái chính
Service order
text
order_new
-> order_in_progress
-> order_completed | order_force_completed
-> order_canceledProduct order
text
new
-> confirmed
-> delivering
-> completed | canceledPrepaid order
text
prepaid_new
-> prepaid_inprogress
-> prepaid_completed | prepaid_force_completed
-> prepaid_canceledThanh toán và invoice
Mỗi order có thể có:
- parent invoice,
- nhiều sub-invoice,
- partial payment,
- wallet promotion amount,
- draft invoice,
- debt amount tính toán.
Quy tắc nghiệp vụ
| Mã | Quy tắc |
|---|---|
| BR-ORD-001 | Service order tạo order trước; nếu có payment thì group payment theo payment_method_id rồi gọi createInvoiceTransaction. |
| BR-ORD-002 | Product order đi nhánh khác: tạo cosmetic order rồi insert invoice trực tiếp ở FE, không hoàn toàn đi qua action chuẩn như service/prepaid. |
| BR-ORD-003 | createInvoiceTransaction yêu cầu tổng parent invoice khớp tổng sub-invoice. |
| BR-ORD-004 | Prepaid dùng sub.amount; service/cosmetic dùng sub.reference_amount. |
| BR-ORD-005 | Ví khuyến mãi chỉ áp dụng cho item allow_promo_wallet = true, sai điều kiện sẽ fail hard. |
Commission
text
Invoice success
-> invoice event
-> tính commission theo order kind / service config
-> ghi order_commission, order_commission_user
-> wallet side effects / notificationQuy tắc nghiệp vụ
| Mã | Quy tắc |
|---|---|
| BR-ORD-006 | Commission của service order gắn chặt với cấu hình service, không chỉ là % chung của order. |
| BR-ORD-007 | Partial payment có thể tạo commission theo sub-invoice. |
| BR-ORD-008 | Refund success có thể kéo theo rollback commission ở wallet event chứ không nằm ngay trong action approve. |
Refund / Withdraw / Commission payout
Refund/withdraw không chỉ là “đổi status order”, mà là tạo request riêng qua wallet.transaction_request.
Behaviors chính
| Behavior | Ý nghĩa |
|---|---|
refund_order | Hoàn service order |
refund_order_cosmetic | Hoàn product order |
refund_topup | Hoàn topup ví |
refund_collaborator | Chi / hoàn liên quan collaborator / payout |
Luồng
text
Tạo withdraw/refund request
-> chờ duyệt
-> changeStatusTransaction
-> wallet event insert/update
-> update revenue / refund log / order refunded flag
-> có thể sinh refund commissionQuy tắc nghiệp vụ
| Mã | Quy tắc |
|---|---|
| BR-ORD-009 | Refund order/cosmetic khi approve sẽ hủy các refund request khác cùng reference_id + branch_id. |
| BR-ORD-010 | refund_topup có thể split giữa VND và VND_PROMOTION. |
| BR-ORD-011 | Refund cash yêu cầu chứng từ. |
| BR-ORD-012 | Wallet refund và cash refund có revenue treatment khác nhau; wallet refund còn net lại transaction nạp ví. |
Negative payment
Negative payment là subdomain riêng, không nên gộp với refund thường.
text
Tạo negative payment
-> invoice âm (`negative=true`)
-> tạo request approval trong HRM
-> approval flow riêng
-> side effects commission âm / request linkQuy tắc nghiệp vụ
| Mã | Quy tắc |
|---|---|
| BR-ORD-013 | Chỉ tạo negative payment khi order chưa paid_at và chưa có request pending. |
| BR-ORD-014 | Với service/cosmetic, negative payment còn tính commission âm để trình duyệt. |
| BR-ORD-015 | Negative payment bám request_working_schedule, không bám transaction_request. |
Prepaid order rules đặc thù
| Mã | Quy tắc |
|---|---|
| BR-ORD-016 | Mỗi card/gói phải có ít nhất 1 commission dương. |
| BR-ORD-017 | Commission không được vượt giá trị card/thực nạp. |
| BR-ORD-018 | prepaid_value_into_wallet tính khác nhau giữa prepaid_type_card và prepaid_type_flexible. |
RBAC thực tế
| Action | Staff | Manager | Admin |
|---|---|---|---|
| Tạo order runtime | Có | Có | Có |
| Xem branch data | Có | Có | Có |
| Force complete / deep ops | Không | Một phần | Có |
| Tạo refund request | Thường không | Có | Có |
| Duyệt refund | Không | Có (một số cấp) | Có |
| Duyệt negative payment | Không | Theo approver flow | Có / approver phù hợp |
Rủi ro / Findings
| Mức | Mô tả |
|---|---|
| P1 | Product order diverge mạnh với service/prepaid vì invoice còn được insert trực tiếp ở FE. |
| P1 | Refund detail và negative detail có dấu hiệu check approver sai theo created_by thay vì current user. |
| P1 | transaction_request.reference_id bị overload, không phải field canonical tuyệt đối. |
| P1 | negative payment nếu bị mô tả như “refund/đảo thanh toán” sẽ sai mô hình dữ liệu thực. |
| P2 | WithdrawRequestCreate có fallback amount 40000000, là default nguy hiểm. |
Thuật ngữ
| Thuật ngữ | Định nghĩa |
|---|---|
| Parent / sub invoice | Cấu trúc hóa đơn chính và các phần thanh toán con |
invoice_draft | Đơn đang ở trạng thái draft invoice |
wallet_promotion_amount | Số tiền từ ví khuyến mãi dùng cho invoice |
refund_topup | Hoàn topup ví khách |
negative payment | Invoice âm + approval request riêng |