電商訂單狀態機設計指南:從「待付款」到「已退款」的完整狀態流轉

電商訂單狀態機設計指南:從「待付款」到「已退款」的完整狀態流轉

很多團隊在專案初期只設計了「未付款」和「已付款」兩個訂單狀態,等到要處理退款、超時關單、部分出貨時才發現整個系統邏輯千瘡百孔。訂單狀態機的設計不是事後修補的工作,而是電商系統的地基。

一個涵蓋金流場景的訂單狀態機,至少需要以下十個狀態:待付款(Pending Payment)、付款處理中(Payment Processing)、已付款(Paid)、備貨中(Preparing)、已出貨(Shipped)、已完成(Completed)、取消待退(Cancellation Pending)、已取消(Cancelled)、退款處理中(Refund Processing)、已退款(Refunded)。

為什麼需要「付款處理中」這個過渡狀態?因為在 ATM 轉帳或超商代碼的場景下,消費者取得繳款資訊後可能數小時甚至數天後才付款。在這段時間內,訂單既不是「未付款」也不算真正在等待——它有了一組虛擬帳號或超商代碼,有明確的繳款期限。將這個階段獨立出來,有助於後續做庫存保留策略和逾期自動關單。

狀態之間的轉換必須嚴格定義合法路徑。例如,「已完成」只能由「已出貨」轉入,而「已退款」可以由「已付款」、「備貨中」、「已出貨」、「已完成」四個狀態觸發——但觸發條件不同。從「已付款」退款通常是全額退款且尚未出貨;從「已完成」退款則可能涉及退貨物流,流程更長。建議在程式碼中使用狀態機框架或至少用一個 transition map(狀態轉換表)來管理,避免散落在各處的 if-else 判斷。

與金流串接時要特別注意的是:訂單狀態的更新應由伺服器端的 Webhook(ReturnURL)驅動,而不是由前端跳轉頁面(OrderResultURL)驅動。前端跳轉可能因為使用者關閉瀏覽器而遺失,它只適合用來顯示「感謝購買」頁面。將狀態更新的權責放在後端 Webhook handler,並加上冪等性檢查,才是安全的做法。

退款狀態同樣需要細分。綠界的信用卡退款分為「取消關帳」和「退刷」兩種操作,前者適用於當天尚未結帳的交易,後者適用於已關帳的交易。你的退款狀態機最好能反映這兩條路徑,否則客服在操作時會不知道該觸發哪個 API。

最後一個建議:每次狀態轉換都應該寫入一筆獨立的狀態變更紀錄(order_status_logs),包含變更時間、變更前後狀態、觸發來源(系統自動、客服手動、金流回調)和相關的交易編號。這張 log 表在排查問題時價值極高,也是對帳時還原事實的依據。

分享文章: