WooCommerce 4+新增订单状态后邮件通知无法发送的修复咨询
解决WooCommerce自定义订单状态邮件不发送的问题
嘿,我帮你排查下这个问题——你的代码里有几个关键问题导致邮件发不出来,还有批量操作的逻辑也没补全,咱们一步步来修正:
先说说你代码里的几个坑
- 你直接复用了「处理中订单」的邮件对象,这不仅会干扰原本的处理中邮件逻辑,还因为钩子绑定不准确,导致自定义状态的邮件触发失败
- 只给批量操作下拉加了选项,但没写实际修改订单状态的处理逻辑,批量改状态根本不会生效
- 邮件动作的绑定方式不够严谨,没有对应到自定义状态变更的触发点
修正后的完整代码
把下面的代码替换你当前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 ); } }
接下来要做的:创建邮件模板
这个自定义邮件需要对应的模板文件,你可以这么弄:
- 打开你的子主题目录,新建
woocommerce/emails/文件夹 - 在里面创建
customer-awaiting-delivery.php文件,内容可以复制WooCommerce默认的customer-processing-order.php模板(在WooCommerce插件目录的templates/emails/里),然后修改成你想要的内容 - 同样,在
emails/里新建plain/文件夹,创建customer-awaiting-delivery.php,复制默认的plain/customer-processing-order.php模板修改即可
关于代码存放位置
你把代码放在主题的functions.php里是对的,但强烈推荐用子主题,因为主题更新会覆盖父主题的functions.php,子主题的文件不会受影响。如果代码太多,也可以自己写个简单的自定义插件来放这些代码,管理起来更方便。
最后测试下
- 手动修改一个订单的状态为
Kargoya Verildi,看看客户邮箱有没有收到邮件 - 试试批量修改订单状态,看能不能成功,有没有提示
- 如果还是收不到,去WooCommerce后台的「设置」→「邮件」里看看这个自定义邮件是不是启用了,也可以用WooCommerce自带的邮件测试工具(在邮件设置页面底部)检查邮件发送功能是否正常
内容的提问来源于stack exchange,提问作者Alperen Eroğlu
相关产品推荐
相关产品推荐

