WooCommerce:woocommerce_order_status_completed_notification钩子执行问题排查
WooCommerce订单完成通知钩子问题排查
问题背景
我的电商网站安装了WooCommerce 8.0.3,现有ID为123、状态为processing的订单。在特定场景下执行以下代码,期望触发customer_completed_order邮件(后台已启用该邮件),但该邮件有时发送成功,有时失败:
// Make sure e-mails are initialized. WC()->mailer(); // Set order status to completed. $order = wc_get_order( 123 ); $order->update_status( "completed", "", true );
经排查发现,customer_completed_order邮件由woocommerce_order_status_completed_notification钩子触发,于是修改代码添加检测:
WC()->mailer(); $order = wc_get_order( 123 ); $order->update_status( "completed", "", true ); var_dump( did_action( "woocommerce_order_status_completed" ) ); var_dump( did_action( "woocommerce_order_status_completed_notification" ) );
检测结果为:
int(1) int(0)
这表明woocommerce_order_status_completed钩子已执行,但woocommerce_order_status_completed_notification钩子未执行。现提出两个问题:
woocommerce_order_status_completed_notification这类钩子在WooCommerce代码中的执行位置在哪里?- 为何
woocommerce_order_status_completed钩子已执行,而woocommerce_order_status_completed_notification钩子未执行?
问题1:钩子执行位置
woocommerce_order_status_{status}_notification这类钩子的触发逻辑在WooCommerce核心文件includes/class-wc-order.php的send_order_status_notifications方法中。
当调用update_status更新订单状态时,方法内部会在状态更新完成后调用send_order_status_notifications,该方法会根据新状态动态拼接出对应的通知钩子(比如woocommerce_order_status_completed_notification),然后通过do_action触发执行。
问题2:钩子未执行的可能原因
结合你的场景,主要有以下几种可能性:
- 订单状态未发生实际变更:如果代码执行时,订单当前状态已经是
completed(比如重复触发状态更新操作),send_order_status_notifications会直接跳过通知流程,钩子自然不会触发。 - 通知触发的上下文限制:若代码在特殊上下文(如AJAX请求、后台批量操作的特定阶段)执行,可能存在邮件初始化不完整的情况——即便调用了
WC()->mailer(),部分场景下邮件类的通知回调仍未被正确注册,导致钩子触发逻辑被跳过。 - 第三方插件/自定义代码干扰:部分插件会修改WooCommerce的通知逻辑,比如通过
woocommerce_order_status_changed钩子拦截通知触发,或者直接禁用特定状态的通知;另外,如果有自定义代码移除了woocommerce_order_status_completed_notification的关联回调,也会导致钩子未被触发。 - 内部过滤逻辑拦截:
send_order_status_notifications方法会检查woocommerce_send_order_status_changed_notifications过滤器的返回值,若有代码将该过滤器设为false,会直接阻止通知钩子的触发。此外,如果订单状态更新时数据库写入失败,即使woocommerce_order_status_completed钩子触发,通知逻辑也会因状态校验不通过而终止。
内容的提问来源于stack exchange,提问作者Pavel Vybíral
相关产品推荐
相关产品推荐

