You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让WooCommerce订单状态保持为On-Hold,避免自动转为Completed?

解决WooCommerce订单保持“On hold”状态不自动变为“Completed”的方法

原代码失效原因

  • 钩子时机不对:woocommerce_payment_complete仅在支付完成时触发,无法覆盖订单标记发货等其他导致状态变为Completed的场景。
  • 逻辑冗余:循环订单商品没有意义,需求是控制整个订单的状态,而非单个商品。
  • 未阻止状态变更:代码只是重复设置on-hold状态,没有拦截后续触发状态变更的动作。

有效解决方案

方案一:拦截从On hold到Completed的状态转换

通过woocommerce_order_status_transition钩子,直接阻止订单从on-hold状态切换为completed状态:

add_action('woocommerce_order_status_transition', 'prevent_on_hold_to_completed', 10, 3);
function prevent_on_hold_to_completed($order, $old_status, $new_status) {
    // 当订单试图从on-hold变为completed时,强制恢复为on-hold
    if ($old_status === 'on-hold' && $new_status === 'completed') {
        $order->set_status('on-hold');
        $order->save();
    }
}

方案二:严格阻止所有设置Completed状态的操作

如果需要更全面的控制,使用woocommerce_before_order_status_change钩子,在状态变更前直接拦截:

add_action('woocommerce_before_order_status_change', 'prevent_completed_status_for_on_hold', 10, 4);
function prevent_completed_status_for_on_hold($order_id, $new_status, $old_status, $order) {
    // 若当前订单是on-hold状态,禁止切换为completed
    if ($old_status === 'on-hold' && $new_status === 'completed') {
        $order->set_status('on-hold');
        // 可选:添加调试日志,方便排查问题
        error_log("订单 {$order_id} 状态变更被拦截:禁止从 {$old_status} 切换为 {$new_status}");
    }
}

方案三:标记发货时保持On hold状态

如果需要在标记订单发货时仍维持on-hold状态,添加以下代码:

// 移除on-hold订单的“完成订单”操作按钮
add_filter('woocommerce_order_actions', 'remove_complete_action_for_on_hold', 10, 2);
function remove_complete_action_for_on_hold($actions, $order) {
    if ($order->has_status('on-hold')) {
        unset($actions['complete']);
    }
    return $actions;
}

// 标记发货时保持on-hold状态
add_action('woocommerce_mark_order_shipped', 'keep_on_hold_when_shipped', 10, 1);
function keep_on_hold_when_shipped($order_id) {
    $order = wc_get_order($order_id);
    if ($order && $order->has_status('on-hold')) {
        // 保持on-hold状态,同时添加发货备注
        $order->update_status('on-hold', '已寄送换货商品,等待原商品退回');
        // 可自行添加追踪号等发货信息
        $tracking_number = ''; // 替换为实际追踪号
        $carrier = ''; // 替换为实际承运商
        $order->add_order_note("已发货:追踪号 {$tracking_number},承运商 {$carrier}");
    }
}

使用说明

  • 将上述代码添加到当前WordPress主题的functions.php文件中,或使用自定义代码插件(如Code Snippets)管理代码,避免主题更新导致代码丢失。
  • 测试时创建测试订单,模拟支付、发货等操作,确认状态是否保持为on-hold。

内容的提问来源于stack exchange,提问作者Rosalito Udtohan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:40:59