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

WooCommerce 4+新增订单状态后邮件通知无法发送的修复咨询

解决WooCommerce自定义订单状态邮件不发送的问题

嘿,我帮你排查下这个问题——你的代码里有几个关键问题导致邮件发不出来,还有批量操作的逻辑也没补全,咱们一步步来修正:

先说说你代码里的几个坑

  1. 你直接复用了「处理中订单」的邮件对象,这不仅会干扰原本的处理中邮件逻辑,还因为钩子绑定不准确,导致自定义状态的邮件触发失败
  2. 只给批量操作下拉加了选项,但没写实际修改订单状态的处理逻辑,批量改状态根本不会生效
  3. 邮件动作的绑定方式不够严谨,没有对应到自定义状态变更的触发点

修正后的完整代码

把下面的代码替换你当前functions.php里的内容(或者直接追加到末尾就行,推荐用子主题的functions.php,避免主题更新丢代码):

// 注册自定义订单状态 'wc-awaiting-delivery'
add_action( 'init', 'register_awaiting_delivery_order_status', 20 );
function register_awaiting_delivery_order_status() {
    register_post_status( 'wc-awaiting-delivery', array(
        'label'                     => _x( 'Kargoya Verildi', 'Order status', 'woocommerce' ),
        'public'                    => true,
        'exclude_from_search'       => false,
        'show_in_admin_all_list'    => true,
        'show_in_admin_status_list' => true,
        'label_count'               => _n_noop( 'Kargoya Verildi <span class="count">(%s)</span>', 'Kargoya Verildi <span class="count">(%s)</span>', 'woocommerce' )
    ) );
}

// 将自定义状态添加到订单编辑页面的下拉菜单(插在「处理中」后面更合理)
add_filter( 'wc_order_statuses', 'add_awaiting_delivery_to_order_statuses' );
function add_awaiting_delivery_to_order_statuses( $order_statuses ) {
    $new_order_statuses = array();

    foreach ( $order_statuses as $key => $status ) {
        $new_order_statuses[ $key ] = $status;

        // 在处理中状态后插入自定义状态
        if ( 'wc-processing' === $key ) {
            $new_order_statuses['wc-awaiting-delivery'] = _x( 'Kargoya Verildi', 'Order status', 'woocommerce' );
        }
    }

    return $new_order_statuses;
}

// 将自定义状态添加到后台订单列表的批量操作下拉
add_filter( 'bulk_actions-edit-shop_order', 'add_awaiting_delivery_bulk_action' );
function add_awaiting_delivery_bulk_action( $actions ) {
    $actions['mark_awaiting-delivery'] = __( 'Kargoya Verildi', 'woocommerce' );
    return $actions;
}

// 处理批量修改订单状态的动作(之前你没写这块,批量操作点了也白搭)
add_filter( 'handle_bulk_actions-edit-shop_order', 'process_awaiting_delivery_bulk_action', 10, 3 );
function process_awaiting_delivery_bulk_action( $redirect_to, $action, $post_ids ) {
    if ( 'mark_awaiting-delivery' !== $action ) {
        return $redirect_to;
    }

    foreach ( $post_ids as $order_id ) {
        $order = wc_get_order( $order_id );
        if ( $order ) {
            $order->update_status( 'awaiting-delivery', __( '订单通过批量操作标记为Kargoya Verildi', 'woocommerce' ) );
        }
    }

    // 批量操作后返回提示
    $redirect_to = add_query_arg(
        array(
            'bulk_action' => 'marked_awaiting-delivery',
            'changed'     => count( $post_ids ),
        ),
        $redirect_to
    );

    return $redirect_to;
}

// 添加批量操作后的成功提示
add_action( 'admin_notices', 'awaiting_delivery_bulk_action_notice' );
function awaiting_delivery_bulk_action_notice() {
    if ( ! isset( $_REQUEST['bulk_action'] ) || 'marked_awaiting-delivery' !== $_REQUEST['bulk_action'] ) {
        return;
    }

    $changed = intval( $_REQUEST['changed'] );
    printf( '<div id="message" class="updated notice is-dismissible"><p>' . _n( '%d个订单已标记为Kargoya Verildi.', '%d个订单已标记为Kargoya Verildi.', $changed, 'woocommerce' ) . '</p></div>', $changed );
}

// 注册自定义邮件动作
add_filter( 'woocommerce_email_actions', 'add_awaiting_delivery_email_action' );
function add_awaiting_delivery_email_action( $actions ) {
    $actions[] = 'woocommerce_order_status_wc-awaiting-delivery';
    return $actions;
}

// 初始化自定义邮件类(不用复用现有模板,避免冲突)
add_action( 'woocommerce_email_classes', 'add_awaiting_delivery_email_class' );
function add_awaiting_delivery_email_class( $email_classes ) {
    class WC_Email_Customer_Awaiting_Delivery extends WC_Email {

        public function __construct() {
            $this->id             = 'customer_awaiting_delivery';
            $this->customer_email = true;
            $this->title          = __( 'Kargoya Verildi 通知', 'woocommerce' );
            $this->description    = __( '当订单状态变为"Kargoya Verildi"时发送给客户的通知邮件。', 'woocommerce' );
            $this->template_html  = 'emails/customer-awaiting-delivery.php';
            $this->template_plain = 'emails/plain/customer-awaiting-delivery.php';
            $this->placeholders   = array(
                '{order_date}'   => '',
                '{order_number}' => '',
            );

            // 绑定触发钩子
            add_action( 'woocommerce_order_status_wc-awaiting-delivery_notification', array( $this, 'trigger' ), 10, 2 );

            parent::__construct();

            // 设置默认邮件主题和标题
            $this->subject = __( '[{site_title}] Siparişiniz Kargoya Verildi ({order_number})', 'woocommerce' );
            $this->heading = __( 'Siparişiniz Kargoya Verildi', 'woocommerce' );
            $this->recipient = $this->get_option( 'recipient', get_option( 'admin_email' ) );
        }

        // 触发邮件发送
        public function trigger( $order_id, $order = false ) {
            $this->setup_locale();

            if ( $order_id && ! is_a( $order, 'WC_Order' ) ) {
                $order = wc_get_order( $order_id );
            }

            if ( is_a( $order, 'WC_Order' ) ) {
                $this->object                         = $order;
                $this->recipient                      = $this->object->get_billing_email();
                $this->placeholders['{order_date}']   = wc_format_datetime( $this->object->get_date_created() );
                $this->placeholders['{order_number}'] = $this->object->get_order_number();
            }

            if ( $this->is_enabled() && $this->get_recipient() ) {
                $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
            }

            $this->restore_locale();
        }

        // 获取HTML邮件内容
        public function get_content_html() {
            return wc_get_template_html(
                $this->template_html,
                array(
                    'order'         => $this->object,
                    'email_heading' => $this->get_heading(),
                    'sent_to_admin' => false,
                    'plain_text'    => false,
                    'email'         => $this,
                )
            );
        }

        // 获取纯文本邮件内容
        public function get_content_plain() {
            return wc_get_template_html(
                $this->template_plain,
                array(
                    'order'         => $this->object,
                    'email_heading' => $this->get_heading(),
                    'sent_to_admin' => false,
                    'plain_text'    => true,
                    'email'         => $this,
                )
            );
        }

        // 设置邮件选项(在WooCommerce后台邮件设置里能看到)
        public function init_form_fields() {
            $this->form_fields = array(
                'enabled' => array(
                    'title'         => __( '启用/禁用', 'woocommerce' ),
                    'type'          => 'checkbox',
                    'label'         => __( '启用此邮件通知', 'woocommerce' ),
                    'default'       => 'yes',
                ),
                'subject' => array(
                    'title'         => __( '邮件主题', 'woocommerce' ),
                    'type'          => 'text',
                    'description'   => sprintf( __( '默认主题:%s', 'woocommerce' ), $this->subject ),
                    'placeholder'   => '',
                    'default'       => $this->subject,
                    'desc_tip'      => true,
                ),
                'heading' => array(
                    'title'         => __( '邮件标题', 'woocommerce' ),
                    'type'          => 'text',
                    'description'   => sprintf( __( '默认标题:%s', 'woocommerce' ), $this->heading ),
                    'placeholder'   => '',
                    'default'       => $this->heading,
                    'desc_tip'      => true,
                ),
                'email_type' => array(
                    'title'         => __( '邮件类型', 'woocommerce' ),
                    'type'          => 'select',
                    'description'   => __( '选择发送邮件的格式。', 'woocommerce' ),
                    'default'       => 'html',
                    'class'         => 'email_type wc-enhanced-select',
                    'options'       => $this->get_email_type_options(),
                    'desc_tip'      => true,
                ),
            );
        }
    }

    $email_classes['WC_Email_Customer_Awaiting_Delivery'] = new WC_Email_Customer_Awaiting_Delivery();

    return $email_classes;
}

// 当订单状态变为自定义状态时,触发邮件通知
add_action( 'woocommerce_order_status_changed', 'trigger_awaiting_delivery_email', 10, 4 );
function trigger_awaiting_delivery_email( $order_id, $old_status, $new_status, $order ) {
    if ( 'wc-awaiting-delivery' === $new_status ) {
        do_action( 'woocommerce_order_status_wc-awaiting-delivery_notification', $order_id, $order );
    }
}

接下来要做的:创建邮件模板

这个自定义邮件需要对应的模板文件,你可以这么弄:

  1. 打开你的子主题目录,新建woocommerce/emails/文件夹
  2. 在里面创建customer-awaiting-delivery.php文件,内容可以复制WooCommerce默认的customer-processing-order.php模板(在WooCommerce插件目录的templates/emails/里),然后修改成你想要的内容
  3. 同样,在emails/里新建plain/文件夹,创建customer-awaiting-delivery.php,复制默认的plain/customer-processing-order.php模板修改即可

关于代码存放位置

你把代码放在主题的functions.php里是对的,但强烈推荐用子主题,因为主题更新会覆盖父主题的functions.php,子主题的文件不会受影响。如果代码太多,也可以自己写个简单的自定义插件来放这些代码,管理起来更方便。

最后测试下

  1. 手动修改一个订单的状态为Kargoya Verildi,看看客户邮箱有没有收到邮件
  2. 试试批量修改订单状态,看能不能成功,有没有提示
  3. 如果还是收不到,去WooCommerce后台的「设置」→「邮件」里看看这个自定义邮件是不是启用了,也可以用WooCommerce自带的邮件测试工具(在邮件设置页面底部)检查邮件发送功能是否正常

内容的提问来源于stack exchange,提问作者Alperen Eroğlu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 18:32:59