本篇文章更新時間:2023/08/30
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
先說結論:可以!
但原本我的作法就是去設計一個方法,透過 woocommerce_order_status_changed
這勾點來判斷。
// 如果到「處理中」的狀態,就觸發自動完成只有虛擬商品訂單狀態切換的檢查
function mxp_check_order_status_completed($order_id, $old_status, $new_status) {
if ($new_status == 'processing') {
$check_virtual_product = true;
$order = wc_get_order($order_id);
foreach ($order->get_items() as $item_id => $item) {
$product = $item->get_product(); // Get the product object
// Check if the product is virtual
if ($product && !$product->is_virtual()) {
$check_virtual_product = false;
break;
}
}
if ($order && $check_virtual_product === true) {
$order->update_status('completed', '(系統)已自動完成訂單。', true);
}
}
}
add_action('woocommerce_order_status_changed', 'mxp_check_order_status_completed', 1, 3);
但因為有一個站「只要該訂單有使用 Coupon 優惠券」,就會無法改變訂單狀態為「處理中 -> 完成」,有夠詭異。
而經多次測試查找 WooCommerce 核心原始碼,才發現原來訂單作業的流程裡有一個 needs_processing
方法。
public function needs_processing() {
$transient_name = 'wc_order_' . $this->get_id() . '_needs_processing';
$needs_processing = get_transient( $transient_name );
if ( false === $needs_processing ) {
$needs_processing = 0;
if ( count( $this->get_items() ) > 0 ) {
foreach ( $this->get_items() as $item ) {
if ( $item->is_type( 'line_item' ) ) {
$product = $item->get_product();
if ( ! $product ) {
continue;
}
$virtual_downloadable_item = $product->is_downloadable() && $product->is_virtual();
if ( apply_filters( 'woocommerce_order_item_needs_processing', ! $virtual_downloadable_item, $product, $this->get_id() ) ) {
$needs_processing = 1;
break;
}
}
}
}
set_transient( $transient_name, $needs_processing, DAY_IN_SECONDS );
}
return 1 === absint( $needs_processing );
}
這方法會在訂單結帳階段過一個完成付款程序流程,然後判斷是否滿足(虛擬商品而且可下載商品)條件,才會直接到「完成」的訂單狀態。
可以理解預設的條件比較嚴苛,但沒想到如果用上述「訂單狀態」的勾點來自己處理這個需求其實還不是最「道地」XD
可以透過這個 needs_processing()
方法中的勾點來處理:
// 確保驗證訂單的時候不要跑進去「處理中」狀態
function mxp_woocommerce_order_item_needs_processing($is_virtual_or_downloadable_item, $product, $line_item_id) {
// $is_virtual_or_downloadable_item => false 才是不需要經過「處理中」狀態
// 商品是「下載」或是「虛擬」都不需要「處理中」的狀態
if ($product->is_downloadable() || $product->is_virtual()) {
return false;
}
return $is_virtual_or_downloadable_item;
}
add_filter('woocommerce_order_item_needs_processing', 'mxp_woocommerce_order_item_needs_processing', 11, 3);
上述方法也只是單純判斷「只要符合虛擬或下載」的邏輯就直接到「完成」狀態了。實際上可以搭配自己的其他驗證邏輯來處理,也算是很方便~
至於那個只要使用 Coupon 優惠券就不會自動完成的問題,目前還在排查中,線上站才有,本機所有人環境都不會碰到的神秘問題!