促銷是電商拉業績的武器,也是帳務的災難現場。折扣碼、紅利點數、會員折扣、免運門檻——這些單獨看都簡單,但客人會同時用。四種疊在一起,如果沒有規則約束,很快就會疊出一個你不想看到的結果:負毛利,賣一件倒賠一件。
這篇拆一個真實電商的促銷疊加引擎,重點講一件我太常遇到、所以知道非做不可的事:毛利保護。
疊加的兩條基本規則
促銷引擎的核心,是回答「這一堆促銷怎麼一起算」。基本上兩條規則:
- 不同 scope 的可以疊:商品層的折扣、訂單層的滿額折、運費層的免運——它們作用在不同層次,可以一層層疊上去。
- 同 scope 的取最優:同一個商品上有兩個折扣活動,不是兩個都給,是取對客人最有利的那一個(或按規則取其一),不能重複折。
光這兩條就擋掉一堆「同一筆折兩次」的漏洞。但擋不住最危險的那個——疊到負毛利。
為什麼一定要有毛利保護:因為負毛利太常遇到
這一段是我最想強調的,因為負毛利真的太常遇到了。
想像一件成本 80、售價 100 的商品。客人用了會員 9 折(-10)、又用了滿額折抵(-15)、再折抵 20 點紅利(-20)——算下來售價變 55,低於成本 80,這一單直接倒賠 25。而這種組合不是刻意鑽漏洞,是促銷疊加下自然就會發生的:每個活動單獨看都合理,疊在一起就破底。
所以促銷引擎一定要有一條毛利保護上限:不管促銷怎麼疊,最終售價不能低於某個底線(成本、或成本加一個最低毛利)。疊到觸底就停,不再往下折。這條線不是「加分項」,是防止促銷把你賣到破產的保命閥。
(這套系統甚至有「負毛利商品」要走審核才能上架的機制——因為有時候你確實想用賠本品引流,但那要是刻意的決定,不能是促銷疊出來的意外。)
優惠券的併發問題:樂觀鎖
促銷還有一個容易忽略的並發坑:限量優惠券。
「前 100 名結帳送折扣券」——這種限量的東西,跟庫存超賣是同一類問題:一堆人同時搶最後幾張,怎麼保證不會發超過 100 張?
這套系統用的是樂觀鎖:發券的時候,用一個帶條件的更新(UPDATE ... WHERE 剩餘數量 > 0),如果更新影響的筆數是 0,代表券已經被搶光了,直接拋錯拒絕。這比悲觀的行鎖輕量——不用先鎖再判斷,而是「先搶、搶不到才知道沒了」。適合優惠券這種「大部分時候搶得到、偶爾撞上搶光」的場景。
點數也是類似的邏輯:發放(earn)、折抵(burn)都要防併發,而且點數折抵一樣要吃毛利保護——不能讓客人用點數把價格折到負毛利。退貨的時候,點數還要按比例退還(呼應退款那篇的逆向計算)。
收:促銷設計的三個要點
- 疊加規則:不同 scope 可疊、同 scope 取優,先擋掉重複折。
- 毛利保護是保命閥:負毛利會自然疊出來(不是漏洞),一定要有底線,觸底就停。
- 限量優惠券用樂觀鎖:跟超賣同類,
UPDATE WHERE 剩餘>0、影響 0 筆就拒絕。