先決定每個金額由誰負責

購物車顯示的總額看似合理,最後送出的請求卻可能帶另一個數字。顧客的瀏覽器、隱藏欄位、本機資料及網絡請求都可被改動。OWASP 的業務邏輯指引指出,即使商品編號及優惠碼的格式完全正確,瀏覽器傳來的價格仍不能當成可信資料。商店應把商品編號、數量和優惠碼視作要求,由自己的伺服器依有效規則重新查價、核對優惠資格、計算送貨費及應付總額。公司亦要清楚訂明誰可改價、何時生效,否則程式即使重新計算,仍可能採用業務上未批准的價目。

不同系統的職責要分清。商品目錄價目只在所列條件下適用;優惠是一套有期限、適用貨品和使用限制的規則;運費取決於目的地及服務選擇;付款服務只回報它處理的交易,不能代替商店決定賣了甚麼或折扣是否合資格。訂單計算紀錄應寫明所用規則版本、幣種、數量、調整項和最終應付額。日後處理爭議時,員工便不用以今天已改動的商品頁畫面,倒推當日顧客看到甚麼。這是商店需要設計的紀錄,不能假設付款供應商會自動代辦。

進入付款前重新計算

開始付款前,伺服器應重新讀取所選商品及數量,確認仍可出售,採用已核准的現行價目,再以商店規則檢查每項優惠,而非照收瀏覽器傳來的折扣金額。運費應根據已核實地址和所選服務,由商店費率表計算。組合不成立時,要明確停下並說明原因,例如某送貨方式已不覆蓋目的地,或優惠碼不適用於該商品。顧客應有機會先看修訂後金額再同意付款;即使伺服器算術無誤,因購物途中改價而靜悄悄收取新金額,仍會造成另一種顧客問題。

假設顧客選了兩件商品並輸入推廣碼,瀏覽器顯示小計、折扣及送貨費。這些顯示數值只是預覽,不是可直接送往付款服務的命令。伺服器須核對商品數量、優惠適用貨品與使用條件,以及選取的送貨方式,再產生一份載有幣種及有效條件的擬議訂單金額。這只是說明流程的假設情境,並非任何商店的真實價目或成效數據。若付款前庫存、優惠資格或送貨條件有變,舊報價應失效,讓顧客確認新的金額。

把確認金額連到付款要求

顧客完成最後確認時,商店應保存由伺服器核准的報價,再以完全相同的金額及幣種建立付款要求。OWASP 的第三方付款整合指引要求在建立訂單前,由後端核對購物車並重新計算總額。商店訂單編號要與付款服務的交易識別碼關聯,方便之後核對。不能讓另一個瀏覽器請求沿用同一付款連結,卻更改核准金額、幣種或折扣。購物車一旦變動,應按商店預先訂明的取消與重試規則,產生新報價及新付款要求。

不要把顧客返回商店的頁面當成已結算證明。瀏覽器可以關閉、重開或修改返回網址;付款服務通知亦可能延遲或重複。商店必須經供應商文件指定的可信渠道核實付款狀態,再把供應商回報的金額與幣種,同已保存的核准報價比較。金額一致只是必要檢查,還要按供應商定義區分已授權、已收款、失敗及退款等狀態。待付款訂單應否放行屬另一項營運決策;此處的重點是完成付款的金額和交易身分,是否與顧客確認的訂單相符。

遇到變價或不符時明確停下

金額不符不一定是欺詐。員工可能在顧客購物車仍開啟時調價,優惠可能到期,送貨地址也可能移到另一區。商店要預先定義報價何時固定、甚麼情況令其失效。付款前重新計算若出現差額,應顯示改動項目及原因,要求顧客再次確認。若付款後供應商回報的金額不同,先暫停訂單並調查,不應直接改寫商店原訂單去迎合供應商回應。保留兩邊原始紀錄與事件先後次序,員工才可判斷是舊報價、幣種設定、供應商配置,還是有人試圖操縱金額。

四捨五入也要有獨立規則。畫面上的小數、系統儲存的最小貨幣單位,以及運費或其他項目的分攤方式,若沒有指定計算順序與取整位置,可能得到不同答案。每筆金額都要連同幣種保存;單一數字不能說明是港元還是其他貨幣。上線前,用已批准的例子測試折扣超過合資格項目、免運費、合資格與不合資格商品同車,以及確認報價後更改地址等邊界。財務和營運人員應先同意預期結果,再寫成測試;不能因程式庫的預設值,就把未經確認的稅務或取整規則帶入業務流程。

用完整交易驗收和對帳

有用的驗收測試要修改瀏覽器送出的請求,即使畫面表面仍正常。分別試改單價、運費、不合資格優惠碼、負數或過大數量,以及幣種;伺服器應按已批准規則拒絕或重新計算,不能以未核准金額建立付款要求。再跟一宗正常訂單由報價、建立付款、供應商確認到訂單帳目,逐步核對識別碼、幣種及金額。這是直接測試信任邊界,單靠錄製一般付款畫面不能證明安全。商品價目、優惠、運費或付款整合改動後,都應重跑相關案例。

日常營運方面,員工需要看到異常畫面:原已核准的報價、付款參考號、供應商回報金額,以及目前訂單狀態。只有獲授權的人可處理差異,並記錄處理理由。對帳程序既要找出已收款卻配不上訂單的交易,也要找出標為已付款但沒有相應供應商核實紀錄的訂單。這些檢查不能保證每項商業規則都公平或合法,卻能讓公司追溯曾核准甚麼、實際處理甚麼。如果抽樣訂單都無法重建兩者比較,下一個開發工作應先補齊事件與金額紀錄,再增加更複雜的推廣玩法。

讓改價決定可供覆核

改價背後的人與紀錄,應與程式計算一樣清楚。價目更新要有生效時間、受影響商品及適當審批人;推廣活動要保存資格規則,以及結束或撤回原因。在公司既定保存政策容許下,保留舊規則版本,方便解釋當時成立的訂單。客服收到舊價截圖時,便可分辨有效的早前報價、已到期預覽,以及真正的計算錯誤,不必臨時憑印象調整。內部訂單畫面應可查看相關規則版本,但敏感設定及員工操作仍須按職責限制存取。

安排開發、營運及對帳負責人共同覆核,但各自回答不同問題。開發人員追查每項金額在哪裏計算、瀏覽器能否覆蓋;營運核對規則是否符合對顧客作出的承諾;財務確認核准金額、供應商金額與帳目金額能否無歧義地配對。意見不一致時,先寫成測試案例,再加入新的折扣功能。即使付款流程能防止篡改,若送貨例外或幣種處理未定,也可能出錯;反過來,推廣文字寫得再清楚,若伺服器接受瀏覽器送來的折扣額,仍會失去控制。共同紀錄可以連接業務政策與實際程式行為。

顧客看到的金額與內部紀錄要一致,但毋須把內部規則全部公開。確認頁應以一般文字列出商品、數量、送貨選擇、調整項、幣種及應付總額;內部紀錄再補上對帳所需的規則識別碼與付款參考號。若顧客確認後推廣條件改變,系統要按商店公開條款作明確選擇:在仍有效的承諾範圍內維持原報價,或要求顧客重新同意新報價。這取決於商店條款及營運能力,軟件不應靜悄悄自行決定。讓客服與工程人員一起走過此例,因為第一個缺陷線索可能只是顧客問為何帳單與付款畫面不同。

進行前先確認

  • 單價、折扣、運費及幣種是否都由伺服器計算或核實?
  • 已確認報價、付款要求及經核實的供應商結果是否一致?
  • 出現差異時,會否暫停處理並保留雙方原始紀錄?

資料來源及延伸閱讀