最後更新:2026/10/15
實體店最常用的三句話:「買三件算你九折」「滿兩千折兩百」「會員再打九五折」。搬到 WooCommerce,很多店家第一個想到的是優惠券,但優惠券要客人自己輸入代碼,忘了輸入就沒折扣,客人事後要求補退,反而多一道客服。市面上的動態定價外掛可以自動算,不過多半要付年費,設定頁又多到眼花。
這三種折扣用一段程式碼就能自動套用,客人什麼都不用輸入,購物車自己算好。這篇把三種各寫一段,你可以只留需要的那幾段。
不想自己改?把這篇交給 AI
把這篇的網址(或全文)連同下面這段話貼給 AI:
我的網站是 WordPress,有裝 WooCommerce。我想照下面這篇文章,讓購物車自動套用折扣:買幾件打幾折、滿多少折多少、會員另有折扣。
請先問我:我要哪幾種折扣、門檻和折數各是多少、適用哪些分類的商品、會員價是給所有登入的客人還是特定角色。
問清楚之後,再一步一步告訴我:要用哪一段程式碼、貼在哪裡、哪些地方要換成我自己的資料,以及改完怎麼測試。
如果文章的做法不適合我的網站,請直接告訴我原因和替代做法。
文章:(貼上這篇的網址,或整篇內容)
改之前先備份,密碼不要貼給 AI。
先把規則寫成一張表
寫程式之前,先把折扣規則寫清楚,越具體越好。例如:
- 數量折扣:「禮盒」分類的商品,同一件買 3 件以上每件 9 折,6 件以上每件 85 折。
- 滿額折扣:購物車小計滿 2,000 元折 200 元。
- 會員價:有登入的客人,所有商品再打 95 折。
這三條就是下面程式碼的設定。你要改門檻、折數或分類,都是改最上面那幾行數字和代稱,不用動後面的邏輯。
完整程式碼
// 第 75 篇:數量折扣、滿額折扣、會員價,不用外掛
// 設定:哪些分類有數量折扣,買幾件以上打幾折
function mimi_discount_rules() {
return [
'gift' => [[6, 15], [3, 10]], // 分類代稱 gift:6 件以上 85 折、3 件以上 9 折(大的數量寫前面)
];
}
// 找出這件商品適用的規則
function mimi_discount_rule_for($product) {
$id = $product->get_parent_id() ?: $product->get_id();
foreach (mimi_discount_rules() as $cat => $tiers) {
if (has_term($cat, 'product_cat', $id)) {
return $tiers;
}
}
return null;
}
// 1. 數量折扣:同一件商品買到門檻,單價打折(改的是購物車裡的價格,商品頁的原價不變)
add_action('woocommerce_before_calculate_totals', function ($cart) {
foreach ($cart->get_cart() as $item) {
$tiers = mimi_discount_rule_for($item['data']);
if (!$tiers) {
continue;
}
foreach ($tiers as [$qty, $percent]) {
if ($item['quantity'] >= $qty) {
$base = (float) $item['data']->get_regular_price();
$item['data']->set_price(round($base * (100 - $percent) / 100));
break;
}
}
}
}, 20);
// 2. 商品頁列出折扣門檻,客人才知道多買有優惠
add_action('woocommerce_single_product_summary', function () {
global $product;
$tiers = $product ? mimi_discount_rule_for($product) : null;
if (!$tiers) {
return;
}
$lines = [];
foreach (array_reverse($tiers) as [$qty, $percent]) {
$lines[] = sprintf('買 %d 件以上,每件 %s 折', $qty, rtrim(rtrim(number_format(100 - $percent, 1), '0'), '.') / 10);
}
echo '<p class="mimi-tiers">' . esc_html(implode(';', $lines)) . '</p>';
}, 15);
// 3. 滿額折扣:小計滿 2,000 折 200(用「費用」做成負的金額,結帳頁會多一行)
add_action('woocommerce_cart_calculate_fees', function ($cart) {
$subtotal = (float) $cart->get_subtotal();
if ($subtotal >= 2000) {
$cart->add_fee('滿 2,000 折 200', -200, false);
}
});
// 4. 會員價:登入的客人再打 95 折(放在數量折扣之後)
add_action('woocommerce_before_calculate_totals', function ($cart) {
if (!is_user_logged_in()) {
return;
}
foreach ($cart->get_cart() as $item) {
$item['data']->set_price(round($item['data']->get_price() * 0.95));
}
}, 30);
程式碼放在 Code Snippets 這類外掛或子主題,放法和備份方式見〈WooCommerce 結帳頁改成台灣習慣〉。
四段各做了什麼
最上面的設定表是整篇的開關。'gift' => [[6, 15], [3, 10]] 的意思是:分類代稱 gift 的商品,6 件以上折 15%(85 折),3 件以上折 10%(9 折)。門檻大的要寫在前面,程式會從大的開始比對,符合就停。要加第二個分類,就照樣再寫一列。分類代稱在「商品 > 分類」每個分類的「代稱」欄位。
第 1 段在購物車算總額之前,看每一列商品買了幾件,達到門檻就把單價換成折扣後的價格。注意它改的是購物車裡那一份商品的價格,商品頁和商店列表的原價不會變,客人看到的還是定價,進購物車才會看到便宜。價格用「一般價格」算,所以本來就在特價的商品不會再被折一次。
第 2 段把規則印在商品頁的價格下面:「買 3 件以上,每件 9 折;買 6 件以上,每件 8.5 折」。折扣沒有講出來,客人不會多買;這一行就是讓客人湊件數的理由。
第 3 段是滿額折扣。WooCommerce 沒有「負的折扣」這個欄位,但有「費用」,費用可以是負數,所以用一筆 -200 元的費用,名稱叫「滿 2,000 折 200」,結帳頁和訂單上會多一行寫著這個名稱和 -200。門檻用的是購物車小計,也就是數量折扣算完之後的金額。
第 4 段是會員價。有登入的客人,每一件商品在前面算完的價格上再打 95 折,這一段排在數量折扣之後,所以會員買 3 件禮盒是先 9 折再 95 折。你如果只想給特定角色(例如「批發客戶」)會員價,把 is_user_logged_in() 換成檢查角色的條件就可以。
測試結果
我們在本機測試站把「手工皂禮盒」(450 元)放進禮盒分類來測:
- 商品頁顯示「買 3 件以上,每件 9 折;買 6 件以上,每件 8.5 折」。
- 訪客買 3 件:單價變成 405 元,小計 1,215,沒有滿額折扣,總計 1,295(含運費 80)。
- 加到 6 件:單價 383 元(450 × 0.85 = 382.5,四捨五入),小計 2,298,出現「滿 2,000 折 200」-200,總計 2,178。
- 會員(buyer)登入買 1 件:單價 428 元(450 × 0.95 = 427.5,四捨五入)。
小數的處理要留意:9 折和 85 折算出來可能有 0.5,程式用四捨五入到整數元,你如果習慣無條件捨去,把 round 改成 floor。
折扣和優惠券、免運怎麼配
這些自動折扣和優惠券可以同時存在,客人輸入優惠券會在自動折扣之後再扣。要避免「折上折再折」把利潤折光,常見的做法是促銷期間停用優惠券,或在優惠券設定裡勾「個別使用」。進階的優惠券玩法可以看〈WooCommerce 優惠券進階用法〉。
免運門檻也要一起想。滿額折扣讓小計變少,但免運看的通常是折扣前的小計,兩個門檻設得接近時,客人會算不清楚。建議把規則寫在購物車上方或商品頁,例如「滿 2,000 折 200,滿 1,000 免運」,一句話講完,客人就不用猜。
促銷規則寫進網站,才不用每天人工改價
實體店的折扣靠老闆一句話,網店的折扣要靠規則。規則寫進程式之後,週年慶改個數字就上線,活動結束再把數字改回來,不用一件一件改商品價格,也不會漏改。
如果你的網店常辦活動,想把折扣、免運、會員制度一起規劃清楚,可以先看〈IG 帳號不是你的資產〉想想網站要做到什麼,會員制度怎麼設計可以看〈會員制、訂閱制怎麼做?〉。MIMI 專做客製化網頁設計,購物車電商網站可以依你的促銷方式設計。MIMI 提供新北網頁設計服務,新北的店家可以用電話、Email 直接和設計師討論;費用可以先看首頁的製作費用參考,歡迎聯絡 MIMI。
