WooCommerce: Send a Custom Email on Order Status Change

If you use custom WooCommerce order statuses, or wish to target an order status transition that is not default (e.g. when order goes from “Processing” to “Completed”, the Completed email triggers – but what if you want to target a transition from “Processing” to “Custom Status”?), sending custom emails is quite complex.

First of all, they won’t show under WooCommerce > Settings > Emails (unless you code it, true) – second, no email will trigger. So, how do they do it?

Send a custom email when an order is marked with custom status – WooCommerce

Snippet (PHP): Send WooCommerce Email @ Custom Order Status

/**
 * @snippet       Send Formatted Email @ WooCommerce Custom Order Status
 * @how-to        Get CustomizeWoo.com FREE
 * @sourcecode    https://businessbloomer.com/?p=91907
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 3.5.7
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */
 
// Targets custom order status "refused"
// Uses 'woocommerce_order_status_' hook
 
add_action( 'woocommerce_order_status_refused', 'bbloomer_status_custom_notification', 20, 2 );
 
function bbloomer_status_custom_notification( $order_id, $order ) {
     
    $heading = 'Order Refused';
    $subject = 'Order Refused';
 
    // Get WooCommerce email objects
    $mailer = WC()->mailer()->get_emails();
 
    // Use one of the active emails e.g. "Customer_Completed_Order"
    // Wont work if you choose an object that is not active
    // Assign heading & subject to chosen object
    $mailer['WC_Email_Customer_Completed_Order']->heading = $heading;
    $mailer['WC_Email_Customer_Completed_Order']->settings['heading'] = $heading;
    $mailer['WC_Email_Customer_Completed_Order']->subject = $subject;
    $mailer['WC_Email_Customer_Completed_Order']->settings['subject'] = $subject;
 
    // Send the email with custom heading & subject
    $mailer['WC_Email_Customer_Completed_Order']->trigger( $order_id );
 
    // To add email content use https://businessbloomer.com/woocommerce-add-extra-content-order-email/
    // You have to use the email ID chosen above and also that $order->get_status() == "refused"
     
}

Where to add this snippet?

You can place PHP snippets at the bottom of your child theme functions.php file (delete "?>" if you have it there). CSS, on the other hand, goes in your child theme style.css file. Make sure you know what you are doing when editing such files - if you need more guidance, please take a look at my free video tutorial "Where to Place WooCommerce Customization?"

Does this snippet (still) work?

Please let me know in the comments if everything worked as expected. I would be happy to revise the snippet if you report otherwise (please provide screenshots). I have tested this code with Storefront theme, the WooCommerce version listed above and a WordPress-friendly hosting on PHP 7.3.

If you think this code saved you time & money, feel free to join 14,000+ WooCommerce Weekly subscribers for blog post updates or 250+ Business Bloomer supporters for 365 days of WooCommerce benefits. Thank you in advance :)

Need Help with WooCommerce?

Check out these free video tutorials. You can learn how to customize WooCommerce without unnecessary plugins, how to properly configure the WooCommerce plugin settings and even how to master WooCommerce troubleshooting in case of a bug!

Rodolfo Melogli

Business Bloomer Founder

Author, WooCommerce expert and WordCamp speaker, Rodolfo has worked as an independent WooCommerce freelancer since 2011. His goal is to help entrepreneurs and developers overcome their WooCommerce nightmares. Rodolfo loves travelling, chasing tennis & soccer balls and, of course, wood fired oven pizza.

32 thoughts on “WooCommerce: Send a Custom Email on Order Status Change

  1. Hi Rodolfo,

    Just wanted to ask what is the best way to apply this PHP code if my theme is deactivated because I am using Oxygen Builder.?

    Many Thanks,
    oli

    1. Use the Code Snippets plugin

  2. Hi there,
    I have a status using this plugin named “reminder”. Now I have also created email template for that reminder as well.
    Now I want to add this email as trigger in processing order email. I mean to say that whenever I change status from reminder to processing. The processing email should be sent to customer. It is not sending right now.
    How can I achieve this?
    Thanks

    1. Hi Mujahid thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  3. Hi, how can I change the snippet to send emails for 2 different custom order statuses? Thanks

    1. Hi Radek, thanks so much for your comment! Yes, this is definitely possible, but Iโ€™m afraid itโ€™s custom work. If youโ€™d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  4. Hi, We used a plugin to add custom “shipped” status to order and used your snippet to send customer email with customized heading and subject. It works perfectly for a while, and we only noticed a problem since this morning:

    the email can still be send out after changing order status to “shipped”(that means it still triggers the action),
    but the custom subject and headings are gone, our customers are getting “Order completed email” including heading and subject.

    Any updated from WordPress or Woocommerce that caused the issue? what other way to change subject or heading of the email?

    Thanks a lot

    1. Hi Damon, that’s weird. To troubleshoot, disable all plugins but WooCommerce and also switch temporarily to “Twentytwenty” theme (load the snippet there in functions.php) as explained here: https://www.businessbloomer.com/lesson/trwm4l01/

      Once you do that, does it work? If yes, you have a problem with your current theme or one of the plugins.

      Hope this helps!

  5. Hi Rodolfo ,

    I have put a comment here before but it doesn’t seem to have been approved…

    Everything works wonderfully well but it will only send the email if it specifies the WC_Email_Customer_Completed_Order email. If you try and specify one that is unused such as ‘On Hold’ and use the correct hooks, it fails and won’t finish the cycle. Change it back to the completed order email and works again without issue.

    Any thoughts why this may be? The email is turned on, not used for anything else and I have re-created this on two different sites? Thank you

    1. Sorry I have no idea. Sure the On Hold is enabled?

  6. Hi Rodolfo, it’s not working on my website…

    1. function wpblog_wc_register_post_statuses() {
      register_post_status( 'wc-shipped', array(
      'label' => _x( 'Shipped', 'WooCommerce Order status', 'text_domain' ),
      'public' => true,
      'exclude_from_search' => false,
      'show_in_admin_all_list' => true,
      'show_in_admin_status_list' => true,
      'label_count' => _n_noop( 'Approved (%s)', 'Approved (%s)', 'text_domain' )
      ) );
      }
      add_filter( 'init', 'wpblog_wc_register_post_statuses' );
      
      function wpblog_wc_add_order_statuses( $order_statuses ) {
      $order_statuses['wc-shipped'] = _x( 'Shipped', 'WooCommerce Order status', 'text_domain' );
      return $order_statuses;
      }
      add_filter( 'wc_order_statuses', 'wpblog_wc_add_order_statuses' );
      
      /**
       * @snippet       Send Formatted Email @ WooCommerce Custom Order Status
       * @how-to        Get CustomizeWoo.com FREE
       * @sourcecode    https://businessbloomer.com/?p=91907
       * @author        Rodolfo Melogli
       * @compatible    WooCommerce 3.5.7
       * @donate $9     https://businessbloomer.com/bloomer-armada/
       */
        
      // Targets custom order status "shipped"
      // Uses 'woocommerce_order_status_' hook
        
      add_action( 'woocommerce_order_status_shipped', 'bbloomer_status_custom_notification', 20, 2 );
        
      function bbloomer_status_custom_notification( $order_id, $order ) {
            
          $heading = 'Order Shipped';
          $subject = 'Order Shipped';
        
          // Get WooCommerce email objects
          $mailer = WC()->mailer()->get_emails();
        
          // Use one of the active emails e.g. "Customer_Completed_Order"
          // Wont work if you choose an object that is not active
          // Assign heading & subject to chosen object
          $mailer['WC_Email_Customer_Completed_Order']->heading = $heading;
          $mailer['WC_Email_Customer_Completed_Order']->settings['heading'] = $heading;
          $mailer['WC_Email_Customer_Completed_Order']->subject = $subject;
          $mailer['WC_Email_Customer_Completed_Order']->settings['subject'] = $subject;
        
          // Send the email with custom heading & subject
          $mailer['WC_Email_Customer_Completed_Order']->trigger( $order_id );
        
          // To add email content use https://businessbloomer.com/woocommerce-add-extra-content-order-email/
          // You have to use the email ID chosen above and also that $order->get_status() == "shipped"
            
      }
      
      1. Sure “shipped” is the correct email ID?

        1. I’m sorry but what do you mean by email ID? Completely new to PHP ๐Ÿ™

          1. Hi it’s now working! There’s conflict with my other plugin.

            1. The only problem is it doesn’t send email to gmail or yahoo. I can only receive notification from the custom status if sending to my own email domain.

              1. Not sure Jackie, but well done for figuring that out

  7. Hi it’s not working for me ๐Ÿ™ I’ve changed “refused” to “shipped”.

  8. Hey! How can I get a webhook for a custom order status and By replacing the webhook of refuse from the above code, will It work as same

    1. Hi Mudit, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  9. Hi,

    I’m looking to create 2 Order Statuses for Preorders.

    Preorder On-hold (Before Payment) –> Copy Email template from On-Hold
    Preorder Processing (Confirmed after Payment) –> Copy Email template from Processing

    There will be a Preorder Stock status as well, how can I create that using functions.php too?

    Preorder On-hold will be triggered when Customer buys a Preorder product(Preorder stock status), and pends for BACS payment like the rest of the normal instock items.

    Preorder Processing will be manually triggered by myself when Customer made payment.

    I actually see that its possible to create using your above coding but got confused…… I supposed the Order status should be separately created? (Your Order Status here is Refused)

    Thanks.

    1. Yes

  10. How to get custom mails as admin for order payment finished via PayPal? When you don’t use the PayPal notifications because it’s the secondary PayPal mail.

    1. Hi Andre, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  11. Hey, where am I supposed to include the custom status slug/name? I see you commented that I should include “$order->get_status() == “refused” ” but where? Cheers!

    1. Hey Joao! Just change “refused” with your custom order slug here:

      add_action( 'woocommerce_order_status_refused'
  12. Hi, thank you for this information. I’m interested in the following. After a payment is made in Woocommerce we place the order into ‘Processing’ than 5 business days later we change the status to ‘Awaiting Shipping’, using the following plugin to add a custom email then after the item ships we mark the order status as ‘Completed’.

    We would like to automate the part that changes the status to ‘Awaiting Shipping’. Is that possible? So after 5 business days, the order status updates automatically to Awaiting Shipping.

    1. Hi there, thanks so much for your comment! Yes, this is definitely possible, but I’m afraid it’s custom work. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding!

  13. Hey, will this allow my website to send “delivery on route” emails? Also are these emails automatic after installing your code ?

    1. Hello Jacqui, yes & yes ๐Ÿ™‚

  14. Where do I add content from https://businessbloomer.com/woocommerce-add-extra-content-order-email/
    Within same function ?
    Pl advice with example. thanks.

    1. Hey Kumar, it’s explained in the snippet comments. Unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

Questions? Feedback? Support? Leave your Comment Now!
_____

If you are writing code, please wrap it between shortcodes: [php]code_here[/php]. Failure to complying with this (as well as going off topic, not writing in English, etc.) will result in comment deletion. You should expect a reply in about 2 weeks - this is a popular blog but I need to get paid work done first. Please consider joining BloomerArmada to get blog comment reply priority, ask me 1-to-1 WooCommerce questions and enjoy many more perks. Thank you :)

Your email address will not be published. Required fields are marked *