本篇文章更新時間: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 方法。

file

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 優惠券就不會自動完成的問題,目前還在排查中,線上站才有,本機所有人環境都不會碰到的神秘問題!


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[///////////____36%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


文章
Filter
Apply Filters
Mastodon