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

WooCommerce修改订单状态时如何仅触发一次指定函数?

WooCommerce订单状态切换触发短信的问题修复

问题回顾

使用woocommerce_order_status_changed钩子实现订单切换到confirmed/packing/shipped状态时发送对应语言短信,但出现两个问题:

  1. 切换到任意指定状态时,三个状态对应的短信都会被触发
  2. 计费国家非FR/BE时,仍发送法语短信

错误原因分析

  1. 条件逻辑写法错误:$order->get_billing_country() == "FR" || "BE" 会被PHP解析为($order->get_billing_country() == "FR") || "BE",非空字符串"BE"在布尔判断中永远为true,导致所有if条件恒成立,所有短信都会发送。
  2. 状态判断不够精准:使用$order->has_status()不如直接利用钩子提供的$to_status参数,后者直接对应订单切换后的目标状态。
  3. 代码冗余且存在语法错误:重复的判断逻辑冗余,且send_sms_function调用中缺少参数分隔逗号。

修复后的代码

add_action( 'woocommerce_order_status_changed', 'trigger_sms_on_new_status', 15, 4 );
function trigger_sms_on_new_status( $order_id, $from_status, $to_status, $order ) { 
    // 定义需要触发短信的目标状态
    $target_statuses = ['confirmed', 'packing', 'shipped'];
    // 若目标状态不在列表中,直接退出
    if( !in_array( $to_status, $target_statuses ) ) return;

    // 获取订单相关数据
    $firstname = $order->get_billing_first_name();
    $phone     = $order->get_billing_phone();
    $shopname  = get_option( 'woocommerce_email_from_name');
    $country   = $order->get_billing_country();

    // 判断是否为法语区国家(FR/BE)
    $is_french_region = in_array( $country, ['FR', 'BE'] );

    // 根据目标状态和地区生成对应短信内容
    switch( $to_status ) {
        case 'confirmed':
            $sms_text = $is_french_region 
                ? "Bonjour $firstname, votre commande #$order_id de $shopname..." 
                : "Hello $firstname, your order #$order_id from $shopname...";
            break;
        case 'packing':
            $sms_text = $is_french_region 
                ? "Bonjour $firstname, votre commande #$order_id de $shopname est en cours de préparation..." 
                : "Hello $firstname, your order #$order_id from $shopname is being prepared...";
            break;
        case 'shipped':
            $sms_text = $is_french_region 
                ? "Bonjour $firstname, votre commande #$order_id de $shopname a été expédiée..." 
                : "Hello $firstname, your order #$order_id from $shopname has been shipped...";
            break;
        default:
            $sms_text = '';
    }

    // 确保手机号和短信内容有效,再发送短信
    if( !empty($sms_text) && !empty($phone) ) {
        send_sms_function( $phone, $sms_text, $shopname );
        $order->add_order_note( 'SMS sent with success.' );
    }
}

修复说明

  • 精准过滤状态:通过in_array检查目标状态,仅在切换到指定状态时执行后续逻辑,避免无关触发。
  • 修正国家判断:用in_array正确判断国家是否为FR/BE,避免逻辑运算符优先级导致的错误。
  • 简化代码结构:使用switch-case统一处理不同状态的短信内容,减少冗余,提升可维护性。
  • 增加有效性校验:判断手机号和短信内容非空,避免无效的短信发送调用。
  • 修复语法错误:补全send_sms_function调用中缺失的参数分隔逗号。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 19:41:06