如果你在 WooCommerce 商店使用 J&T Express 插件,你可能注意到一个令人困惑的现象:即使客户的付款在支付网关失败或被取消,他们仍会收到 “Order Processing” 邮件。
截至 2026 年 2 月 13 日,这个问题在插件当前的 trunk 版本中依然存在。以下是问题成因与修复方法的分析。
问题所在:全局邮件触发
问题出在 jt-express/admin/class-jnt-status.php 里的 order_status_changed_notification 函数。
插件挂接到 woocommerce_order_status_changed 钩子。然而,代码的结构使得 “Processing Order” 邮件的 trigger() 方法在每次任何状态变化时都会被调用,无论新状态是否符合 J&T 的自定义物流状态。
有问题的代码
在原始文件(约第 88 行)中,逻辑是这样的:
public function order_status_changed_notification($order_id, $status_from, $status_to)
{
$mailer = WC()->mailer()->get_emails();
// If/Else checks for J&T statuses...
// BUG: These lines run on EVERY status change (e.g., Pending -> Failed)
$mailer['WC_Email_Customer_Processing_Order']->settings['subject'] = $subject;
$mailer['WC_Email_Customer_Processing_Order']->settings['heading'] = $heading;
$mailer['WC_Email_Customer_Processing_Order']->trigger($order_id);
}
由于 trigger() 调用没有被包在条件判断里,WooCommerce 即使在订单刚从待付款变成失败时,也会发出 “Processing” 邮件。
解决方案:条件逻辑
要修复这个问题,我们需要确保只有当 $status_to 符合 J&T 特定的物流状态(jnt-pending、jnt-pickup 或 jnt-out-delivery)之一时,才触发这封邮件。
优化后的修复方案
用以下代码替换 class-jnt-status.php 中的这个函数:
public function order_status_changed_notification($order_id, $status_from, $status_to)
{
$mailer = WC()->mailer()->get_emails();
// 1. Define our target statuses
$target_statuses = ['jnt-pending', 'jnt-pickup', 'jnt-out-delivery'];
// 2. Only proceed if the new status is one of ours
if (in_array($status_to, $target_statuses)) {
// Map statuses to their respective subjects/headings
if ($status_to == 'jnt-pending') {
$subject = $heading = 'Your Order is Pending to Pickup';
} elseif ($status_to == 'jnt-pickup') {
$subject = $heading = 'Your Order has been Picked up';
} elseif ($status_to == 'jnt-out-delivery') {
$subject = $heading = 'Your Order is out for Delivery';
}
// 3. Trigger the email ONLY for the statuses defined above
$email = $mailer['WC_Email_Customer_Processing_Order'];
$email->settings['subject'] = $subject;
$email->settings['heading'] = $heading;
$email->trigger($order_id);
}
}
为什么这样做有效
通过把逻辑包在 in_array($status_to, $target_statuses) 里,我们建立了一道「守门员」。如果客户取消付款、状态变成 failed,代码会发现 failed 不在我们的 $target_statuses 列表中,于是什么都不做。再也不会误发邮件了!
给开发者的提醒:由于这是对插件核心文件的修改,请记得日后更新插件时可能会覆盖这些改动。建议保留这段修复代码的片段,或联系 J&T 的开发团队,让他们在下一个版本中加入这项验证。
觉得有用?把它分享给其他使用 J&T Express 的网站开发者,帮他们省掉客服上的烦恼!

发表回复
要发表评论,您必须先登录。