11 mins read2022/07/28

Woocommerce 點數扣除/補回的 Hook 選擇


前言

最近的客製化是改寫 Woocommerce 的折價券

原本的 Woocommerce 的折價券 是要輸入 coupon 代碼,極為不人性

改良後:

  1. 列出所有能用的折扣,用選的,不用複製折價代碼
  2. 如果條件符合就可以點選直接使用
  3. 如果不符合(例如總金額不到),會顯示你還差多少錢,再去多買個東西就可以使用折扣

此案例有使用到類似點數的概念 – 購物金

 

遭遇的問題

用戶持有的購物金,在選擇不同優惠券時,會一直被扣除

問題狀況如下:

用戶一開始選 消費滿99,可用購物金折抵10元,此時用戶的購物金會被扣除10元

再換成 消費滿999,可用購物金折抵100元,此時用戶的購物金會被扣除10元,但先前的10元不會還給用戶

再切換就會再扣,不會還給用戶

 

代碼

我原本是使用 woocommerce_applied_coupon 這隻 Hook

字面翻譯是:當優惠券被應用的時候



function point_reduct(){
    //我的扣點函式
}
add_action( 'woocommerce_applied_coupon', 'point_reduct' );

確實,我上方的代碼確實是在優惠券被應用的時候,執行扣點

但這樣做,會產生上述的 Bug – 每次只是應用優惠券,就被扣點了

 

Woocommerce 的 Hook…

其實 Woocommerce 的文件跟 WordPress 相比並不算很完整

Woocommerce  把所有的 Hook, 物件方法都列出來,然後…自己看原始碼吧🤪

woocommerce_applied_coupon 這隻 Hook 為例,我在 Woocommerce Code Reference 查到

然後會連到 class-wc-cart.php 叫你看原始碼🤪

Woocommerce 表示:懶得多做解釋,自己看 Code 好嘛!

好吧,其實有好的程式碼註解,不會太難看懂

而且 Automattic 它們只有 5% 的時間貢獻開源專案,其他時間要做公司的產品啊!所以沒時間寫文件也是合理!

 

核心思路

  1. 不應該使用 woocommerce_applied_coupon 這隻 Hook,因為這隻 Hook 的時機不是我們要的
  2. 應該是 訂單有成立 ( 完成 / 處理中 ) 才扣點,訂單如果不成立 ( 取消 / 等待付款中 ) 就不扣點
  3. Woocommerce Code Reference 尋找類似的關鍵字,例如 complete, status
  4. 思考什麼東西也是跟規則2雷同 – 庫存 stock

就當我漫無目的地尋找時…我看到了有可能會有關的方法名稱 woocommerce_payment_complete_reduce_order_stock

我點進去看時,下方的 Action Hook 立馬吸引了我的注意

最上方英文註解已經有說明這函式的用途了

⭐ 上面這段白話說就是 – 當付款完成時,訂單狀態為 已完成 / 處理中 / 保留 時,扣除庫存

再往下看一下

最上方英文註解已經有說明這函式的用途了

⭐ 上面這段白話說就是 – 當訂單狀態為 取消 / 等待付款中 時,將庫存還原

BINGO! 😀

其實上面這些就是我們要找的 Action Hook ,可以如法炮製

 

解法



/**
 * 付款完成時、訂單[完成][處理中][保留]時,將點數扣除
 */
function point_reduct_with_coupon(){
    // 我的扣點函式
}
add_action( 'woocommerce_payment_complete', 'point_reduct_with_coupon' );
//add_action( 'woocommerce_order_status_completed', 'point_reduct_with_coupon' );
//add_action( 'woocommerce_order_status_processing', 'point_reduct_with_coupon' );
//add_action( 'woocommerce_order_status_on-hold', 'point_reduct_with_coupon' );

/**
 * 訂單[取消][等待付款中]時,將點數補回
 */
function point_restore_with_coupon(){
    // 我的補點函式
}
add_action( 'woocommerce_order_status_cancelled', 'point_restore_with_coupon' );
//add_action( 'woocommerce_order_status_pending', 'point_restore_with_coupon' );

2022/08/21更新

因為 woocommerce_payment_complete 以及 woocommerce_order_status_completed / woocommerce_order_status_processing / woocommerce_order_status_on-hold 可能會使訂單狀態不同時產生重複扣點

最後只使用結帳完成時 woocommerce_payment_complete 來判斷扣點

訂單取消時 woocommerce_order_status_cancelled 判斷點數補回

覺得不錯的話,請給我點個推薦

您的支持與鼓勵是我們前進的最大動力!