WP笔记

WooCommerce订单状态变化与邮件发送的关系

WooCommerce订单状态更新时会发送邮件,系统默认的邮件有自己的触发条件,当触发条件满足时,邮件就会自动发送。本文大体描述了这个过程。

WooCommerce订单状态变化触发邮件发送的过程

订单状态由pending变为processing并发送admin new order的过程:

1. 调用$order->update_status( ‘processing’ )更新状态,触发提示状态变化的action,如下所示

// abstract-wc-order.php
public function update_status( $new_status, $note = '', $manual = false ) {
    ...
    do_action( 'woocommerce_order_status_' . $new_status, $this->id );
    do_action( 'woocommerce_order_status_' . $old_status . '_to_' . $new_status, $this->id );
    do_action( 'woocommerce_order_status_changed', $this->id, $old_status, $new_status );
    ...
}

这时会触发woocommerce_order_status_pending_to_processing这个action

2. 触发send_transactional_email()函数

// class-wc-emails.php
public static function init_transactional_emails() {
    $email_actions = apply_filters( 'woocommerce_email_actions', array(
        ...
        'woocommerce_order_status_pending_to_processing',
        ...
    ) );

    foreach ( $email_actions as $action ) {
        add_action( $action, array( __CLASS__, 'send_transactional_email' ), 10, 10 );
    }
}

代码执行了add_action( ‘woocommerce_order_status_pending_to_processing’, array( __CLASS__, ‘send_transactional_email’ ), 10, 10 );
进而触发send_transactional_email()函数。

3. 触发发送邮件的action

// class-wc-emails.php
public static function send_transactional_email() {
    self::instance();
    $args = func_get_args();
    do_action_ref_array( current_filter() . '_notification', $args );
}

相当于执行了do_action( ‘woocommerce_order_status_pending_to_processing_notification’ );

4. 发送邮件

WooCommerce会加载所有注册过的email classes,但只有满足触发条件的才能执行。

// class-wc-email-new-order.php
add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_pending_to_completed_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'trigger' ) );
add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'trigger' ) );

admin new order执行了add_action( ‘woocommerce_order_status_pending_to_processing_notification’, array( $this, ‘trigger’ ) ),trigger()函数负责发送邮件,当运行do_action( ‘woocommerce_order_status_pending_to_processing_notification’ )时,该函数会被执行,进而邮件被发给管理员。

综上所述,更新订单状态时,如果状态变化符合某个邮件的触发条件,该邮件就会被发送。

实际执行顺序

  1.  init_transactional_emails
  2.  update_status
  3.  send_transactional_email
  4.  trigger

发送邮件的函数

function wc_mail( $to, $subject, $message, $headers = "Content-Type: text/html\r\n", $attachments = "" ) {
	$mailer = WC()->mailer();

	$mailer->send( $to, $subject, $message, $headers, $attachments );
}

21条评论

  1. 不知道博主还在不,想问一个问题,就是我的woo在用户使用paypal支付成功以后,订单状态还是不变,依旧是未支付,要手动去改变才行

    1. paypal的状态需要通过接受伊布通知来实现,可能是你服务器配置有问题,或者拦截了来自paypal的请求。
      去woocommerce的系统工具里看看,里面会显示必须安装的服务是否装了,如果没有装全就用不了paypal。

  2. /?add-to-cart=28 是添加 ID 为 28 的商品到购物车的URL参数,那么能否同时添加两个商品呢?比如 ID 为 28 和 26 的这两个商品。

    1. 网址不小心输成zhu.kr结果还是你,冰天雪地神豬一枚是你家猪吗,都长这么霸气了!

        1. 嗯,在群里看了看这只猪你发了好多次,真是霸气侧漏。我家猪跟他比太瘦了,我得多喂喂,猪还是肥肥的好看。

  3. sola,请问您的网站都做了哪些有话?比如,缓存插件/CDN等优化细节,呵呵,多谢

        1. 嗯,使用minify插件时很容易出这个问题,因为压缩后可能更改js脚本加载顺序,导致某些脚本无法工作。

          可以试试把验证码相关的脚本从minify里排除,可能就好了。

评论已关闭。