結帳全部算完,最後才一次寫進資料庫。


很多人的結帳流程是這樣寫的:

建立訂單 → 算商品小計 → 更新訂單 → 套用折扣 → 寫一筆折扣 → 更新訂單
→ 算運費 → 更新訂單 → 扣點數 → 更新訂單 → 發回饋點數 → 更新訂單

一路上,資料庫被改了六次。

這種寫法有三個問題,而且都會在上線後咬你。

第一,中途失敗會留下半張訂單。 折扣寫進去了、運費還沒算,程式就噴了。資料庫裡躺著一張金額是錯的訂單,客服看到它,不知道該怎麼辦。

第二,沒辦法試算。 老闆問「這張購物車如果加上新活動會變多少錢?」你答不出來,因為你的計算流程一跑就會寫進資料庫。你不可能為了回答一個問題就下一張假單。

第三,測試很痛。 要測一條折扣規則,得先準備會員、商品、訂單、促銷設定,跑完再檢查五張表。這種測試沒有人想寫,所以最後就不寫了——偏偏這是最需要測試的地方。

我的做法:把一次結帳切成兩段

第一段:算              不碰資料庫,從頭算到尾,算出一份結果
第二段:存              拿那份結果,一次寫進資料庫

第一段負責所有的判斷與數學:哪些活動成立、折多少、送什麼、運費多少、最後要收多少錢。它不查資料庫、不寫資料庫、不發信、不呼叫金流。它就是一個函式:餵進去一份購物車,吐出來一份結果。

第二段就簡單到無聊了。它拿到那份算好的結果,照抄進資料表:

'items_subtotal' => $cart->itemsSubtotal(),
'discount_total' => $discountTotal,
'shipping_fee'   => $checkoutState->shippingFee(),
'total'          => $checkoutState->grandTotal(),

寫進資料庫的那段程式碼裡,不該出現任何加減乘除。 這是我檢查自己有沒有寫歪的方法——看到 persistOrder() 裡面開始出現 * 或 floor(),就代表兩段又混在一起了。

換來什麼

要不要建立訂單,是最後才決定的。 算完之後包在一個交易裡一次寫入,中途失敗就什麼都沒發生,不會有半張訂單。

試算變成免費的。 同一段計算可以跑一百次都不會留下痕跡。所以購物車頁、抽屜購物車、結帳頁、後台試算工具,全部共用它,而且保證算出同一個數字。

測試不用開資料庫。 準備一份購物車、呼叫、檢查金額,一秒跑完。促銷規則是最容易算錯的地方,它必須是最好測的地方。

這個模式有名字

它叫 Functional Core, Imperative Shell。

中間那段純計算是 core,外面那圈碰 HTTP、資料庫、金流、寄信的是 shell。

但名字不重要。實務上你只要記得一句話:先算完,再落地。


⭐️ 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
本數據每小時更新一次