訂單狀態與付款系統機制文檔
系統概述
本電商系統採用嚴格的訂單狀態管理機制,透過資料庫觸發器確保狀態轉換的一致性和業務邏輯的正確性。系統支援多種付款方式,並具備自動狀態同步和手動管理功能。
1. 訂單狀態流程
1.1 完整狀態轉換圖
訂單建立 → pending
↓
confirmed (管理員確認/自動確認)
↓
paid (付款完成時自動轉換)
↓
processing (手動:開始處理)
↓
shipped (手動:已出貨,需要物流單號)
↓
delivered (手動:已送達)
↓
completed (手動:訂單完成)
可隨時取消:
Any Status → cancelled → refunded (退款完成)1.2 允許的狀態轉換
sql
-- 由 validate_order_status_transition() 函數控制
('pending', 'confirmed'), -- 待處理 → 已確認
('pending', 'cancelled'), -- 待處理 → 已取消
('confirmed', 'paid'), -- 已確認 → 已付款
('confirmed', 'cancelled'), -- 已確認 → 已取消
('paid', 'processing'), -- 已付款 → 處理中
('paid', 'cancelled'), -- 已付款 → 已取消
('processing', 'shipped'), -- 處理中 → 已出貨
('processing', 'cancelled'), -- 處理中 → 已取消
('shipped', 'delivered'), -- 已出貨 → 已送達
('delivered', 'completed'), -- 已送達 → 已完成
('cancelled', 'refunded') -- 已取消 → 已退款2. 付款系統機制
2.1 支援的付款方式
sql
-- 資料庫約束定義
CHECK ((method = ANY (ARRAY[
'credit_card'::text, -- 信用卡
'paypal'::text, -- PayPal
'bank_transfer'::text, -- 銀行轉帳
'cash_on_delivery'::text -- 貨到付款
])))2.2 付款狀態
sql
-- 付款狀態約束
CHECK ((status = ANY (ARRAY[
'pending'::text, -- 待處理
'completed'::text, -- 已完成
'failed'::text, -- 失敗
'refunded'::text -- 已退款
])))2.3 付款方式差異處理
信用卡/PayPal/銀行轉帳
- 標準流程:
pending→completed - 特點:需要實際付款確認才轉為完成狀態
- 訂單影響:付款完成時自動將訂單狀態設為
paid
貨到付款 (Cash on Delivery)
- 特殊處理:創建時直接設為
completed - 業務邏輯:送貨時收款,視為預先完成的付款
- 避免衝突:防止觸發器將已確認訂單回退到
pending
3. 自動狀態轉換機制
3.1 付款觸發的訂單狀態同步
sql
-- sync_order_status_with_payment() 觸發器邏輯
IF NEW.status = 'pending' THEN
UPDATE orders SET status = 'pending', updated_at = NOW() WHERE id = NEW.order_id;
ELSIF NEW.status = 'completed' THEN
UPDATE orders SET status = 'paid', updated_at = NOW() WHERE id = NEW.order_id;
ELSIF NEW.status = 'failed' THEN
UPDATE orders SET status = 'pending', updated_at = NOW() WHERE id = NEW.order_id;
ELSIF NEW.status = 'refunded' THEN
UPDATE orders SET status = 'refunded', updated_at = NOW() WHERE id = NEW.order_id;3.2 觸發時機
- INSERT 觸發器:新增付款記錄時自動同步
- UPDATE 觸發器:付款狀態變更時自動同步
- 條件觸發:只有在狀態實際改變時才執行
3.3 業務規則驗證
sql
-- check_order_business_rules() 確保:
-- 1. 確認訂單必須有商品項目
-- 2. 付款狀態需要有完成的付款記錄
-- 3. 出貨狀態需要物流單號4. 手動管理場景
4.1 後台管理員操作
場景一:手動標記為已付款
typescript
// 使用 updateOrderToPaid() 處理
// 步驟:
// 1. 檢查訂單狀態,如果是 pending → 先設為 confirmed
// 2. 創建管理員付款記錄(標記為 ADMIN_MANUAL_)
// 3. 觸發器自動將訂單狀態設為 paid場景二:批量狀態更新
typescript
// 批量處理不同狀態的訂單
// 確保每個狀態轉換都符合業務規則場景三:緊急訂單處理
typescript
// 跳過某些驗證步驟,直接進入處理流程
// 但仍需遵循基本的狀態轉換規則4.2 客戶操作
場景一:前台付款
typescript
// 透過 mock-payment Edge Function
// 1. 檢查訂單狀態
// 2. 如需要,先將 pending → confirmed
// 3. 創建付款記錄
// 4. 觸發器自動同步訂單狀態場景二:訂單取消
typescript
// 客戶可在特定狀態下取消訂單
// 通常限制在 pending/confirmed 狀態5. 錯誤處理與衝突避免
5.1 狀態轉換衝突
問題:Invalid status transition from confirmed to pending原因:貨到付款創建 pending 付款記錄,觸發器嘗試將 confirmed 訂單回退到 pending 解決:
typescript
// 在 mock-payment 函數中特殊處理
if (method === 'cash_on_delivery' && status === 'pending' && order.status !== 'pending') {
finalPaymentStatus = 'completed';
}5.2 併發處理
問題:多個操作同時修改訂單狀態 解決:
- 使用資料庫事務確保原子性
- 觸發器提供最終一致性保證
- 前端樂觀鎖定處理併發更新
5.3 資料一致性
問題:付款記錄與訂單狀態不一致 解決:
- 觸發器自動同步機制
- 定期資料完整性檢查
- 管理後台提供手動修復工具
6. 監控與日誌
6.1 狀態變更追蹤
sql
-- 透過 updated_at 欄位追蹤變更時間
-- 透過 order_status_logs 表記錄詳細變更歷史(建議實作)6.2 付款記錄追蹤
sql
-- 每筆付款記錄包含:
-- - transaction_id: 外部交易識別碼
-- - method: 付款方式
-- - status: 付款狀態
-- - paid_at: 付款完成時間
-- - created_at/updated_at: 記錄時間戳7. 系統配置
7.1 Edge Functions
- mock-payment: 模擬付款處理,處理狀態轉換邏輯
- order-create: 建立訂單並扣減庫存
- order-summary: 訂單統計分析
7.2 資料庫觸發器
- validate_order_status_transition: 狀態轉換驗證
- sync_order_status_with_payment: 付款狀態同步
- check_order_business_rules: 業務規則檢查
- calculate_order_total: 訂單金額計算
- generate_order_number: 訂單編號生成
7.3 前端狀態管理
狀態機思維架構
採用輕量級狀態機思維,提供嚴謹的狀態轉換管理:
核心組件:
- 狀態轉換配置 (
ORDER_TRANSITIONS): 定義允許的狀態轉換規則 - 轉換驗證函數 (
validateTransition,canTransitionTo): 前端驗證邏輯 - 智能狀態選擇: 只顯示有效的下個狀態選項
- 確認對話框: 詳細的轉換預覽和業務說明
UI 增強功能:
- 單一訂單操作: 智能狀態選擇和轉換確認
- 批量操作: 預先驗證並分析批量轉換結果
- 錯誤處理: 友善的錯誤訊息和操作指引
- 視覺化指示: 狀態流程圖和轉換預覽
關鍵文件:
types/order.ts: 狀態定義和轉換規則composables/useOrder.ts: 狀態轉換邏輯components/order/OrderStatusTransitionDialog.vue: 單一訂單轉換components/order/BatchStatusTransitionDialog.vue: 批量操作docs/dev-notes/ORDER_STATE_MACHINE_APPROACH.md: 完整設計文檔
7.4 技術整合
- Vue.js Composables: useOrder, usePayment
- TypeScript 型別定義: 確保型別安全和狀態轉換邏輯
- 即時訂閱: 訂單狀態變更的即時通知
- 狀態驗證: 前後端一致的業務規則驗證
8. 最佳實務
8.1 開發建議
- 狀態轉換前先檢查:確認當前狀態允許目標轉換
- 使用事務處理:多步驟操作包裝在事務中
- 錯誤處理完整:為每種異常情況提供處理邏輯
- 日誌記錄詳細:記錄關鍵操作和錯誤資訊
8.2 測試策略
- 單元測試:測試各個狀態轉換函數
- 整合測試:測試完整的訂單生命週期
- 壓力測試:測試併發訂單處理能力
- 邊界測試:測試異常狀態和錯誤情況
8.3 維護注意事項
- 資料庫觸發器變更:需要完整測試,避免破壞既有邏輯
- 狀態定義修改:需要同時更新前後端程式碼
- 付款方式新增:需要評估對現有邏輯的影響
- 效能監控:觀察觸發器對資料庫效能的影響
9. 故障排除
9.1 常見問題
狀態轉換被拒絕
- 檢查
validate_order_status_transition邏輯 - 確認業務規則是否滿足
- 檢查
付款狀態同步失敗
- 檢查觸發器是否正常執行
- 查看錯誤日誌確認具體原因
前端狀態顯示不一致
- 確認即時訂閱是否正常工作
- 檢查前端快取機制
9.2 除錯工具
- 資料庫查詢:直接查看訂單和付款記錄狀態
- 日誌分析:透過應用程式日誌追蹤操作流程
- 管理後台:提供訂單狀態修復工具
本文檔會隨系統演進持續更新,確保與實際實作保持一致。