WooCommerce自定义订单状态邮件无法触发的排查求助
WooCommerce自定义订单状态邮件无法触发排查
我开发的插件里注册了自定义订单状态,但切换到/从这些状态(包括和processing、completed等核心状态互转)时,邮件触发不了。我已经注册了所有能想到的动作组合(业务场景排除了on-hold和pending),请问哪里漏了?
初始类代码
<?php /** * @author BAKKBONE Australia * @package Bkf_WC_Email * @license GNU General Public License (GPL) 3.0 **/ if ( ! defined( 'ABSPATH' ) ) { return; } /** * Class Bkf_WC_Email */ class Bkf_WC_Email { /** * Bkf_WC_Email constructor. */ public function __construct() { add_action( 'woocommerce_email_classes', array( $this, 'bkf_register_email' ), 90, 1 ); define( 'CUSTOM_WC_EMAIL_PATH', plugin_dir_path( __FILE__ ) ); add_filter('woocommerce_email_actions', array($this, 'bkf_woocommerce_email_actions'), 10, 1); } /** * @param array $emails * * @return array */ public function bkf_register_email( $emails ) { $emails['WC_Email_Customer_Scheduled_Order'] = include __DIR__ . 'emails/class-wc-customer-scheduled-order.php'; $emails['WC_Email_Customer_Prepared_Order'] = include __DIR__ . 'emails/class-wc-customer-made-order.php'; $emails['WC_Email_Customer_Out_for_Delivery_Order'] = include __DIR__ . 'emails/class-wc-customer-out-order.php'; return $emails; } public function bkf_woocommerce_email_actions($actions) { $actions[] = 'woocommerce_order_status_scheduled'; $actions[] = 'woocommerce_order_status_made'; $actions[] = 'woocommerce_order_status_out'; $actions[] = 'woocommerce_order_status_relay'; $actions[] = 'woocommerce_order_status_processing'; $actions[] = 'woocommerce_order_status_completed'; $actions[] = 'woocommerce_order_status_scheduled_to_made'; $actions[] = 'woocommerce_order_status_scheduled_to_out'; $actions[] = 'woocommerce_order_status_scheduled_to_relay'; $actions[] = 'woocommerce_order_status_scheduled_to_processing'; $actions[] = 'woocommerce_order_status_scheduled_to_completed'; $actions[] = 'woocommerce_order_status_made_to_scheduled'; $actions[] = 'woocommerce_order_status_made_to_out'; $actions[] = 'woocommerce_order_status_made_to_relay'; $actions[] = 'woocommerce_order_status_made_to_processing'; $actions[] = 'woocommerce_order_status_made_to_completed'; $actions[] = 'woocommerce_order_status_out_to_scheduled'; $actions[] = 'woocommerce_order_status_out_to_made'; $actions[] = 'woocommerce_order_status_out_to_relay'; $actions[] = 'woocommerce_order_status_out_to_processing'; $actions[] = 'woocommerce_order_status_out_to_completed'; $actions[] = 'woocommerce_order_status_relay_to_scheduled'; $actions[] = 'woocommerce_order_status_relay_to_made'; $actions[] = 'woocommerce_order_status_relay_to_out'; $actions[] = 'woocommerce_order_status_relay_to_processing'; $actions[] = 'woocommerce_order_status_relay_to_completed'; $actions[] = 'woocommerce_order_status_processing_to_scheduled'; $actions[] = 'woocommerce_order_status_processing_to_made'; $actions[] = 'woocommerce_order_status_processing_to_out'; $actions[] = 'woocommerce_order_status_processing_to_relay'; $actions[] = 'woocommerce_order_status_processing_to_completed'; $actions[] = 'woocommerce_order_status_completed_to_scheduled'; $actions[] = 'woocommerce_order_status_completed_to_made'; $actions[] = 'woocommerce_order_status_completed_to_out'; $actions[] = 'woocommerce_order_status_completed_to_relay'; $actions[] = 'woocommerce_order_status_completed_to_processing'; $bkfoptions = get_option("bkf_options_setting"); if($bkfoptions["bkf_petals"] == "1") { $actions[] = 'woocommerce_order_status_new'; $actions[] = 'woocommerce_order_status_accept'; $actions[] = 'woocommerce_order_status_reject'; $actions[] = 'woocommerce_order_status_scheduled_to_new'; $actions[] = 'woocommerce_order_status_scheduled_to_accept'; $actions[] = 'woocommerce_order_status_scheduled_to_reject'; $actions[] = 'woocommerce_order_status_made_to_new'; $actions[] = 'woocommerce_order_status_made_to_accept'; $actions[] = 'woocommerce_order_status_made_to_reject'; $actions[] = 'woocommerce_order_status_out_to_new'; $actions[] = 'woocommerce_order_status_out_to_accept'; $actions[] = 'woocommerce_order_status_out_to_reject'; $actions[] = 'woocommerce_order_status_relay_to_new'; $actions[] = 'woocommerce_order_status_relay_to_accept'; $actions[] = 'woocommerce_order_status_relay_to_reject'; $actions[] = 'woocommerce_order_status_processing_to_new'; $actions[] = 'woocommerce_order_status_processing_to_accept'; $actions[] = 'woocommerce_order_status_processing_to_reject'; $actions[] = 'woocommerce_order_status_completed_to_new'; $actions[] = 'woocommerce_order_status_completed_to_accept'; $actions[] = 'woocommerce_order_status_completed_to_reject'; $actions[] = 'woocommerce_order_status_new_to_scheduled'; $actions[] = 'woocommerce_order_status_new_to_made'; $actions[] = 'woocommerce_order_status_new_to_out'; $actions[] = 'woocommerce_order_status_new_to_relay'; $actions[] = 'woocommerce_order_status_new_to_processing'; $actions[] = 'woocommerce_order_status_new_to_completed'; $actions[] = 'woocommerce_order_status_new_to_accept'; $actions[] = 'woocommerce_order_status_new_to_reject'; $actions[] = 'woocommerce_order_status_accept_to_scheduled'; $actions[] = 'woocommerce_order_status_accept_to_made'; $actions[] = 'woocommerce_order_status_accept_to_out'; $actions[] = 'woocommerce_order_status_accept_to_relay'; $actions[] = 'woocommerce_order_status_accept_to_processing'; $actions[] = 'woocommerce_order_status_accept_to_completed'; $actions[] = 'woocommerce_order_status_accept_to_new'; $actions[] = 'woocommerce_order_status_accept_to_reject'; $actions[] = 'woocommerce_order_status_reject_to_scheduled'; $actions[] = 'woocommerce_order_status_reject_to_made'; $actions[] = 'woocommerce_order_status_reject_to_out'; $actions[] = 'woocommerce_order_status_reject_to_relay'; $actions[] = 'woocommerce_order_status_reject_to_processing'; $actions[] = 'woocommerce_order_status_reject_to_completed'; $actions[] = 'woocommerce_order_status_reject_to_new'; $actions[] = 'woocommerce_order_status_reject_to_accept'; } return $actions; } } new Bkf_WC_Email();
特定邮件类代码
<?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly } if ( ! class_exists( 'WC_Email' ) ) { return; } /** * Class WC_Email_Customer_Out_for_Delivery_Order */ class WC_Email_Customer_Out_for_Delivery_Order extends WC_Email { /** * Create an instance of the class. * * @access public * @return void */ function __construct() { $this->id = 'customer_out_order'; $this->title = __( 'Order Out for Delivery', 'woocommerce' ); $this->description = __( 'An email sent to the customer when an order is out for delivery.', 'woocommerce' ); $this->customer_email = true; $this->heading = __( 'Order Out for Delivery', 'woocommerce' ); $this->subject = sprintf( _x( '[%s] Order Out for Delivery', 'default email subject for out for delivery emails', 'woocommerce' ), '{blogname}' ); $this->template_html = 'emails/customer-out-order.php'; $this->template_plain = 'emails/plain/customer-out-order.php'; $this->template_base = CUSTOM_WC_EMAIL_PATH . 'templates/'; add_action( 'woocommerce_order_status_out', array( $this, 'trigger' ) ); parent::__construct(); } /** * Trigger Function that will send this email to the customer. * * @access public * @return void */ function trigger( $order_id ) { $this->object = wc_get_order( $order_id ); if ( version_compare( '3.0.0', WC()->version, '>' ) ) { $order_email = $this->object->billing_email; } else { $order_email = $this->object->get_billing_email(); } $this->recipient = $order_email; 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. * * @access public * @return string */ public function get_content_html() { return wc_get_template_html( $this->template_html, array( 'order' => $this->object, 'email_heading' => $this->get_heading(), 'additional_content' => $this->get_additional_content(), 'sent_to_admin' => false, 'plain_text' => false, 'email' => $this ), '', $this->template_base ); } /** * Get content plain. * * @return string */ public function get_content_plain() { return wc_get_template_html( $this->template_plain, array( 'order' => $this->object, 'email_heading' => $this->get_heading(), 'additional_content' => $this->get_additional_content(), 'sent_to_admin' => false, 'plain_text' => true, 'email' => $this ), '', $this->template_base ); } } return new WC_Email_Customer_Out_for_Delivery_Order();
排查思路
自定义状态注册是否合规:确保自定义状态(如
scheduled、made等)注册时,public属性设置为true,否则WooCommerce不会触发对应的状态切换钩子。示例注册代码:add_action('init', 'register_custom_order_statuses'); function register_custom_order_statuses() { register_post_status('wc-out', array( 'label' => __('Out for Delivery', 'text-domain'), 'public' => true, // 必须为true 'show_in_admin_status_list' => true, 'label_count' => _n_noop('Out for Delivery <span class="count">(%s)</span>', 'Out for Delivery <span class="count">(%s)</span>', 'text-domain') )); } add_filter('woocommerce_order_statuses', 'add_custom_status_to_list'); function add_custom_status_to_list($statuses) { $statuses['wc-out'] = __('Out for Delivery', 'text-domain'); return $statuses; }邮件触发钩子不完整:当前邮件类只绑定了
woocommerce_order_status_out钩子,但状态切换时还需要绑定woocommerce_order_status_{from}_to_out系列钩子。比如在WC_Email_Customer_Out_for_Delivery_Order的构造函数里补充:// 基础进入状态钩子 add_action( 'woocommerce_order_status_out', array( $this, 'trigger' ) ); // 所有切换到out状态的钩子 add_action( 'woocommerce_order_status_scheduled_to_out', array( $this, 'trigger' ) ); add_action( 'woocommerce_order_status_made_to_out', array( $this, 'trigger' ) ); add_action( 'woocommerce_order_status_processing_to_out', array( $this, 'trigger' ) ); add_action( 'woocommerce_order_status_completed_to_out', array( $this, 'trigger' ) ); // petals选项对应的状态切换钩子 $bkfoptions = get_option("bkf_options_setting"); if($bkfoptions["bkf_petals"] == "1") { add_action( 'woocommerce_order_status_new_to_out', array( $this, 'trigger' ) ); add_action( 'woocommerce_order_status_accept_to_out', array( $this, 'trigger' ) ); }检查后台邮件启用状态:在WooCommerce后台「设置-邮件」中,确认你的自定义邮件(如"Order Out for Delivery")处于启用状态,
$this->is_enabled()会读取这个配置判断是否发送邮件。调试trigger函数:在
trigger函数开头添加日志,验证钩子是否触发:error_log('Out for Delivery email trigger fired for order ID: ' . $order_id);然后查看服务器错误日志,确认是否进入了触发逻辑。
版本兼容性优化:当前代码中获取订单邮箱的版本判断冗余,直接使用
$this->object->get_billing_email()即可适配新版WooCommerce。
内容的提问来源于stack exchange,提问作者Scott L
相关产品推荐
相关产品推荐

