自定义邮件通知导致WooCommerce默认自动邮件无法发送
WooCommerce自定义发货状态导致默认邮件失效的问题排查
问题描述
为WooCommerce开发「发货与发票」插件时,新增了processing到shipped的订单状态流转(含下拉选择、批量操作),同时添加了订单变为shipped时的客户发货通知邮件。但出现异常:默认自动邮件(如新订单通知、订单完成通知等)无法触发,仅手动发送邮件正常,下单、状态变更等场景无自动邮件。
问题根源分析
1. 邮件动作注册与触发逻辑冲突
- 错误添加
woocommerce_order_status_wc-shipped到邮件动作列表,同时手动绑定send_transactional_email到该动作,干扰了WooCommerce原生邮件触发机制。 - 自定义邮件类中重复绑定
woocommerce_order_status_shipped_notification动作,且直接调用send()方法,未遵循WooCommerce标准邮件触发流程。
2. 邮件类初始化优先级问题
使用20的优先级注册自定义邮件类,可能在原生邮件类初始化前执行,导致原生邮件类被干扰或覆盖。
3. 状态变更动作命名不规范
使用简化版的woocommerce_order_status_shipped动作,而非WooCommerce标准的woocommerce_order_status_to-shipped格式,导致状态变更事件链混乱,影响原生邮件触发。
修复代码方案
步骤1:修正邮件动作注册逻辑
删除冗余手动触发代码,改用原生机制:
add_filter( 'woocommerce_email_actions', 'shipped_email_actions', 20, 1 ); function shipped_email_actions( $actions ) { // 添加标准状态变更动作 $actions[] = 'woocommerce_order_status_to-shipped'; return $actions; } // 移除以下两行冗余代码: // add_action( 'woocommerce_order_status_wc-shipped', array( 'WC_Emails', 'send_transactional_email' ), 10, 1 ); // add_action('woocommerce_order_status_shipped', 'shipped_status_trigger_email_notification', 10, 2 );
步骤2:重构自定义邮件类
移除内部冗余动作绑定,遵循原生触发流程:
class WC_Shipped_Order_Email extends WC_Email { public function __construct() { $this->id = 'customer-shipped-order'; $this->customer_email = true; $this->title = 'Shipped order'; $this->description = 'This notification is sent to customers after shipping, including product details and tracking number.'; $this->template_html = 'emails/customer-shipped-order.php'; $this->placeholders = array( '{order_date}' => '', '{order_number}' => '', ); parent::__construct(); // 绑定标准状态变更动作触发邮件 add_action( 'woocommerce_order_status_to-shipped', array( $this, 'trigger' ), 10, 2 ); } public function trigger( $order_id, $order = false ) { if ( ! $order_id ) return; $this->object = is_a( $order, 'WC_Order' ) ? $order : wc_get_order( $order_id ); if ( ! is_a( $this->object, 'WC_Order' ) ) return; $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() ) return; $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() ); } // 其余方法(get_content_html、init_form_fields)保持不变 }
步骤3:调整邮件类注册优先级
降低优先级,确保原生邮件类先完成初始化:
add_filter( 'woocommerce_email_classes', 'add_shipped_order_woocommerce_email', 30, 1 ); function add_shipped_order_woocommerce_email( $email_classes ) { require( SHIPMENT_INVOICE_PLUGIN_DIR . 'includes/classes/ShippedOrderEmail.php' ); $email_classes['WC_Shipped_Order_Email'] = new WC_Shipped_Order_Email(); return $email_classes; }
步骤4:优化批量状态修改逻辑
添加批量操作处理函数,确保状态变更符合原生流程:
add_action( 'admin_action_mark_shipped', 'handle_bulk_mark_shipped' ); function handle_bulk_mark_shipped() { if ( ! isset( $_POST['post'] ) || ! is_array( $_POST['post'] ) ) return; foreach ( $_POST['post'] as $order_id ) { $order = wc_get_order( $order_id ); if ( is_a( $order, 'WC_Order' ) ) { // 使用update_status触发原生状态变更事件 $order->update_status( 'shipped', 'Bulk marked as shipped' ); } } wp_redirect( wp_get_referer() ); exit; }
验证方法
- 保存代码后,通过WooCommerce后台「状态 > 工具」清除缓存
- 测试下单流程,检查默认新订单邮件是否正常触发
- 将订单从
processing改为shipped,验证自定义发货邮件是否发送 - 测试批量修改订单状态,确认邮件逻辑正常
内容的提问来源于stack exchange,提问作者Volkan Ülkü
相关产品推荐
相关产品推荐

