WooCommerce has the option to defer/background-send its emails instead of sending them while processing the action the visitor has taken. This can have a few benefits for customers visiting your store:
- If their actions on the store are crashing when sending emails (such as the “new account” email), deferring the emails can let the customer continue with their order.
- The site may be more responsive because less work is being performed for each action the customer takes.
However, the background email functionality is newer and less-tested.
The current default (as of this writing in July of 2019) is to send the emails immediately. You may come across other pages mentioning the deferred emails as being the default, but that’s because the default has been changed twice.
Enabling deferred emails
Adding this code to your functions.php (or a plugin file) will cause emails to be sent in a background task:
add_filter( 'woocommerce_defer_transactional_emails', '__return_true' );
Or use this code to ensure the default behavior (sending emails during the processing of the user’s request) in case it’s been changed by other code:
add_filter( 'woocommerce_defer_transactional_emails', '__return_false', PHP_INT_MAX );
Disabling sending of the deferred/background email
I originally thought the
woocommerce_allow_send_queued_transactional_email hook would be useful for temporarily disabling queued mail sending while troubleshooting. But as far as I can tell from digging into the code, the email task will be considered “completed” whether or not it’s allowed to be sent by the filter. However, if that’s useful in some way, you can turn off the sending with:
add_filter( 'woocommerce_allow_send_queued_transactional_email', '__return_false' );
How it works behind the scenes
WooCommerce uses the WP Background Processing library to manage queuing and running the background emails. WC_Email acts as a middleman for the following notifications, forwarding them to their “real” versions which have a “_notification” suffix:
If a custom email needs other notifications, the
woocommerce_email_actions filter can be used to append to the array.
WC_Emails::init_transactional_emails hooks the above email-triggering actions with
queue_transactional_email for background emailing or
send_transactional_email for immediate emailing.
queue_transactional_email uses an instance of
WC_Background_Emailer to queue the hook and its arguments for later execution by WP-Cron. When it’s later executed, it calls back into
WC_Emails::send_queued_transactional_email. If the
woocommerce_allow_send_queued_transactional_email filter (true by default) allows it, the hook appended with “_notification” is executed, allowing the email to be sent. There doesn’t appear to be any conditional logic allowing it to retry later, so I don’t think
woocommerce_allow_send_queued_transactional_email is an effective way of temporarily disabling email you want to send later.
You’ve made it to the end of the article…
…which is a stunning feat. As a reward, here are 3 randomly-generated emojis that will surely tell a compelling story: