客戶按下結帳就建單,不管他後來有沒有付錢。


「訂單什麼時候建立?」這題的答案會決定你的系統好不好維護。

有些人選「付款成功才建立」,理由聽起來很合理:沒付錢的不算訂單,資料庫才不會一堆垃圾。

實際上這條路走不通。

因為有些付款方式,本來就需要訂單先存在。 ATM 虛擬帳號要綁一張單才發得出去,客戶可能三天後才去繳款。超商代碼繳費也一樣。你不可能等他付完錢才建單——他要付給誰?

因為付款失敗你也需要知道。 客戶刷卡被拒,你什麼紀錄都沒有。他打電話來問「我剛剛下單失敗了」,你連他買了什麼都查不到。

我的做法

結帳表單送出、金額算完,第一件事就是建單,狀態一律是:

'status'             => Order::STATUS_DRAFT,
'payment_status'     => Order::PAYMENT_STATUS_UNPAID,
'fulfillment_status' => Order::FULFILLMENT_STATUS_UNFULFILLED,

不管客戶接下來要刷卡、要 ATM、要超商取貨付款,都先走到這一步。付款方式的差異,從下一步才開始。

狀態轉移集中在一個地方

建完單之後,訂單只會被幾個方法推進:

$order->markOpen();        // 訂單成立(ATM 這種還沒付錢的也算成立)
$order->markPaid();        // 付款完成
$order->markCanceled();    // 取消

這些方法全部寫在 Order model 裡面。

重點是:狀態字串不准出現在各個金流的流程裡。 不然你有六種付款方式,就有六個地方在寫 $order->status = 'open',哪天規則要改,你得改六個地方,而且一定會漏。

這樣做順便解決的事

重複通知不會出事。 金流的 notify 會重送,所以 markPaid() 第一行就檢查:已經是 paid 就直接 return。點數結算也以 order_id 去重。外部系統重打十次,結果跟打一次一樣。

通知信只寄一次。 訂單可能先 markOpen() 再 markPaid(),兩次都想寄信。我用一個 confirmation_notified_at 欄位擋住,寄過就不寄了。

draft 是有價值的資料。 那些沒有付款的單,就是「客戶走到最後一步卻放棄」的紀錄。後台看得到、可以打電話追、可以分析哪個付款方式的放棄率特別高。

不要把它當垃圾。 那是你最接近成交的一批客戶。


⭐️ Shopify 網站開發服務(給品牌)
https://job.turn.tw/shopify-services

⭐️ 川川電商事務所(全客製電商開發服務)
https://chuanchuan.tw

⭐️ 台灣 Shopify 商家交流 LINE 群(非官方)
https://line.me/ti/g2/PZ_1LILWVWWuzZQ50HNpYA-A3k6QXWF6znqoBQ

⭐️ 台灣 Shopify 開發者 LINE 群(非官方)
https://line.me/ti/g2/YUasX5K3CJ4QdIx76zppjHlh3-q8w-xkSyK1LA

共有 0 則留言


⭐️ Shopify 網站開發服務(給品牌)
https://job.turn.tw/shopify-services

⭐️ 川川電商事務所(全客製電商開發服務)
https://chuanchuan.tw

⭐️ 台灣 Shopify 商家交流 LINE 群(非官方)
https://line.me/ti/g2/PZ_1LILWVWWuzZQ50HNpYA-A3k6QXWF6znqoBQ

⭐️ 台灣 Shopify 開發者 LINE 群(非官方)
https://line.me/ti/g2/YUasX5K3CJ4QdIx76zppjHlh3-q8w-xkSyK1LA
🏆 本月排行榜
🥇
站長阿川
📝45   💬1  
643
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次