在WooCommerce电商场景中,默认的邮件触发规则仅支持订单状态、付款方式等通用维度的判断,无法满足基于特定商品ID及其元数据的精确触发需求。比如商家需要给购买了ID为123的定制商品,且商品元数据里custom_type值为premium的用户发送专属售后邮件,就需要自定义邮件触发逻辑。

核心实现思路
整个过程主要分为三个步骤:首先监听WooCommerce的订单状态变更钩子,然后在钩子回调中获取当前订单的所有商品信息,接着遍历商品判断是否存在目标商品ID及对应的元数据,最后符合条件时触发自定义邮件发送。
具体实现步骤
1. 监听订单状态变更钩子
WooCommerce在订单状态变更时会触发woocommerce_order_status_changed钩子,我们可以在这个钩子的回调中编写自定义逻辑。以下是基础的钩子注册代码:
add_action('woocommerce_order_status_changed', 'custom_trigger_email_by_product', 10, 4);
function custom_trigger_email_by_product($order_id, $old_status, $new_status, $order) {
// 这里后续编写条件判断和邮件触发逻辑
}2. 获取订单商品并判断条件
通过订单对象可以获取所有购买的商品,再遍历每个商品获取ID和元数据,判断是否符合触发条件。假设我们要触发的条件是:订单状态变为completed,且包含商品ID为123,同时该商品的custom_level元数据值为vip。
add_action('woocommerce_order_status_changed', 'custom_trigger_email_by_product', 10, 4);
function custom_trigger_email_by_product($order_id, $old_status, $new_status, $order) {
// 仅当订单状态变为已完成时执行
if ($new_status != 'completed') {
return;
}
// 目标商品ID
$target_product_id = 123;
// 目标元数据键和值
$target_meta_key = 'custom_level';
$target_meta_value = 'vip';
$is_match = false;
// 遍历订单中的所有商品
foreach ($order->get_items() as $item) {
$product_id = $item->get_product_id();
// 判断商品ID是否匹配
if ($product_id == $target_product_id) {
// 获取商品的元数据
$product = wc_get_product($product_id);
$meta_value = $product->get_meta($target_meta_key);
// 判断元数据是否匹配
if ($meta_value == $target_meta_value) {
$is_match = true;
break;
}
}
}
// 符合条件则触发邮件
if ($is_match) {
custom_send_target_email($order);
}
}3. 注册并发送自定义邮件
WooCommerce的邮件系统基于WC_Email类,我们需要先注册自定义邮件类型,再在符合条件时调用发送方法。以下是注册自定义邮件和发送的完整代码:
// 注册自定义邮件类
add_filter('woocommerce_email_classes', 'register_custom_email_class');
function register_custom_email_class($email_classes) {
require_once 'class-wc-email-custom-product-notice.php';
$email_classes['WC_Email_Custom_Product_Notice'] = new WC_Email_Custom_Product_Notice();
return $email_classes;
}
// 自定义邮件类示例(保存为class-wc-email-custom-product-notice.php)
/*
class WC_Email_Custom_Product_Notice extends WC_Email {
public function __construct() {
$this->id = 'custom_product_notice';
$this->title = '定制商品专属通知';
$this->description = '当订单包含特定ID和元数据的商品并变为已完成时发送';
$this->heading = '您的定制商品已处理完成';
$this->subject = '定制商品处理完成通知';
$this->template_html = 'emails/custom-product-notice.php';
$this->template_plain = 'emails/plain/custom-product-notice.php';
parent::__construct();
}
public function trigger($order_id) {
if (!$order_id) {
return;
}
$this->object = wc_get_order($order_id);
$this->recipient = $this->object->get_billing_email();
if ($this->is_enabled() && $this->get_recipient()) {
$this->send($this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments());
}
}
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
));
}
}
*/
// 触发邮件发送的函数
function custom_send_target_email($order) {
$mailer = WC()->mailer();
$emails = $mailer->get_emails();
if (isset($emails['WC_Email_Custom_Product_Notice'])) {
$emails['WC_Email_Custom_Product_Notice']->trigger($order->get_id());
}
}注意事项
- 商品元数据的获取需要注意,如果是订单项上的元数据,要使用
$item->get_meta()方法,而不是商品本身的元数据方法,避免获取到通用商品属性而非订单专属的定制属性。 - 自定义邮件模板需要放在当前主题的woocommerce/emails目录下,否则WooCommerce无法正确加载模板内容。
- 如果需要支持多个目标商品ID或多种元数据组合条件,可以将目标条件定义为数组,遍历判断即可,逻辑和单个条件类似。
调试建议
开发过程中可以在条件判断处添加日志输出,确认是否正确获取到商品ID和元数据,比如使用error_log()函数打印相关信息到WordPress的调试日志中,方便排查问题。如果邮件没有正常发送,可以先检查自定义邮件类是否注册成功,再检查收件人邮箱是否正确获取,最后确认邮件模板路径是否无误。
WooCommerce自定义邮件触发商品ID元数据条件逻辑修改时间:2026-06-04 06:44:34