WooCommerce: Don’t Send Emails for Free Orders

There are times when you sell free products to give customers access to a membership, an online course, or for other reasons. In these cases, you might not want to send the “Order Completed” email or get the “New Order” transactional notification, so that you can avoid sending and receiving hundreds of emails.

Of course, you’d still want to keep the order emails for amounts above $0. Here’s the fix.

WooCommerce: disable order emails if total is 0

PHP Snippet: Disable WooCommerce Order Emails If Total = 0

/**
 * @snippet       Disable Emails for Free Orders - WooCommerce
 * @how-to        Get CustomizeWoo.com FREE
 * @author        Rodolfo Melogli
 * @compatible    WooCommerce 8
 * @community     https://businessbloomer.com/club/
 */
 
// To target additional emails you can add EMAIL_ID to this filter:
// "woocommerce_email_recipient_EMAIL_ID"
// Find EMAIL_ID: businessbloomer.com/woocommerce-add-extra-content-order-email
 
add_filter( 'woocommerce_email_recipient_customer_completed_order', 'bbloomer_disable_order_email_if_free', 9999, 2 );
add_filter( 'woocommerce_email_recipient_new_order', 'bbloomer_disable_order_email_if_free', 9999, 2 );
 
function bbloomer_disable_order_email_if_free( $recipient, $order ) {
    $page = $_GET['page'] = isset( $_GET['page'] ) ? $_GET['page'] : '';
    if ( 'wc-settings' === $page ) {
        return $recipient; 
    }
    if ( (float) $order->get_total() === '0.00' ) $recipient = '';
    return $recipient;
}

Where to add custom code?

You should place custom PHP in functions.php and custom CSS in style.css of your child theme: where to place WooCommerce customization?

This code still works, unless you report otherwise. To exclude conflicts, temporarily switch to the Storefront theme, disable all plugins except WooCommerce, and test the snippet again: WooCommerce troubleshooting 101

Related content

  • WooCommerce: Add Content to a Specific Order Email
    Customizing WooCommerce emails via the WordPress dashboard is not easy and – sometimes – not possible. For example, you can’t edit or add content to them unless you’re familiar with code. Well, here’s a quick example to learn how to add content to any WooCommerce default order email. In this case study, our goal is […]
  • WooCommerce: How to Add a Custom Checkout Field
    Let’s imagine you want to add a custom checkout field (and not an additional billing or shipping field) on the WooCommerce Checkout page. For example, it might be a customer licence number – this has got nothing to do with billing and nothing to do with shipping. Ideally, this custom field could show above the […]
  • WooCommerce: Get Order Info (total, items, etc) From $order Object
    As a WooCommerce development freelancer, every day I repeat many coding operations that make me waste time. One of them is: “How to get ____ if I have the $order variable/object?“. For example, “How can I get the order total“? Or “How can I get the order items“? Or maybe the order dates, customer ID, […]
  • WooCommerce Visual Hook Guide: Emails
    WooCommerce customizers: the Visual Hook Guide is back! Here’s a visual HTML hook guide for the WooCommerce Emails. This visual guide belongs to my “Visual Hook Guide Series“, that I’ve put together so that you can find WooCommerce hooks quickly and easily by seeing their actual locations. Let me know in the comments if this […]
  • WooCommerce: Allow Users to Edit Processing Orders
    How can WooCommerce customers edit an order they just placed and paid for? I swear I looked on search engine results and other places before coming to the conclusion I needed to code this myself. For example, a user might want to change the delivery date (if you provide this on the checkout page). Or […]

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. Follow @rmelogli

44 thoughts on “WooCommerce: Don’t Send Emails for Free Orders

  1. Hi, This is not working for custom status. eg: add_filter( ‘woocommerce_email_recipient_customer_assembly_order’, ‘hoodsly_email_recipient_customization’, 10, 2 );
    How can I solve this?

    1. Hi Richard 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!

  2. Hi Rudolfo
    Just tried the snippet with WooCommerce 5.5.2 and PHP 7.4.22 – unfortunately it isn’t working.

    1. Update: removed (float) as Sophie suggested, and it works:

      add_filter( 'woocommerce_email_recipient_customer_completed_order', 'bbloomer_disable_customer_order_email_if_free', 10, 2 );
        
      function bbloomer_disable_customer_order_email_if_free( $recipient, $order ) {
          $page = $_GET['page'] = isset( $_GET['page'] ) ? $_GET['page'] : '';
          if ( 'wc-settings' === $page ) {
              return $recipient; 
          }
          if( $order->get_total() == 0 ) $recipient = '';
          return $recipient;
      }
      
        1. My web dev inserted your code for me but it is no longer working. ๐Ÿ™ I read through the comments but don’t see the differences (even using a diff tool).

          I’m inserting the PHP code using My Custom Functions and when I “turn on” the code I get this:

          Sorry, but your code causes a “Fatal error”, so it is not applied!
          Please, check the code and try again.

          It used to work but I can’t figure out what to change now. Please advise. I hate customers getting tons of emails for orders that are “0”. It makes no sense to me!

          /**
           * @snippet       Disable Customer Order Email for Free Orders - WooCommerce
           * @how-to        Get CustomizeWoo.com FREE
           * @author        Rodolfo Melogli
           * @compatible    Woo 3.8
           * @community     https://businessbloomer.com/club/
           */
            
          // To target another email you can change the filter to e.g.:
          // "woocommerce_email_recipient_customer_processing_order"
            
          add_filter( 'woocommerce_email_recipient_customer_completed_order', 'bbloomer_disable_customer_order_email_if_free', 10, 2 );
            
          function bbloomer_disable_customer_order_email_if_free( $recipient, $order ) {
              $page = $_GET['page'] = isset( $_GET['page'] ) ? $_GET['page'] : '';
              if ( 'wc-settings' === $page ) {
                  return $recipient; 
              }
              if( $order->get_total() == 0 ) $recipient = '';
              return $recipient;
          }
          
          1. What’s the Fatal Error description? That should help you and me finding out what’s going on

  3. Hi Rodolfo,
    I works with woo subscriptions emails as well (once you find the correct hook )
    I had to modify your code with another users tip (removing the float)

    if( $order->get_total() == 0 ) $recipient = '';
    1. Nice!

  4. Hi,

    I added the code to functions.php. But still, the order completed mail is going to the customer. My woocommerce Version 4.6.0. Can you please let me know the modified code if any.

    Thanks

    1. Hi Hasan, works for me, sorry. Do you use decimals in your prices (0.00)?

  5. Hi Rodolfo,
    thank you very much for this tip, in my case I would like to disable ADMIN email for new free order, is the following snippet correct please?

    add_filter( 'woocommerce_email_enabled_new_order', 'bbloomer_disable_customer_order_email_if_free', 10, 2 );
      
    function bbloomer_disable_customer_order_email_if_free( $recipient, $order ) {
        $page = $_GET['page'] = isset( $_GET['page'] ) ? $_GET['page'] : '';
        if ( 'wc-settings' === $page ) {
            return $recipient; 
        }
        if ( (float) $order->get_total() === '0.00' ) $recipient = '';
        return $recipient;
    }
    

    Thanks!
    Ludovic (from Reunion island)

    1. Hey Ludovic, no you need to change this hook only: woocommerce_email_recipient_customer_completed_order

      1. Thank you for your reply, for new order email to the admin, this hook is the good one please?
        woocommerce_order_status_pending_to_completed_notification

        1. No, the filter would be ‘woocommerce_email_recipient_admin_new_order’ (untested)

  6. Thanks for this great code, Rodolfo!
    I had to adapt the code as AlbanS suggested – our page runs on php 7.4.8

    1. Nice!

  7. Thank you for this incredible code!
    I want to also disable the email for a particular product. How can I achieve that?

    TIA

    1. Hi Vincent, 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!

  8. Hello,

    Thank you very much for your article.
    Can this work to deactivate notification emails for a new order?
    I do not wish to receive emails for free orders.

    I have try (WC 3.8.1) :

    add_filter( 'woocommerce_email_recipient_new_order', 'bbloomer_disable_customer_order_email_if_free', 10, 2 );

    But doesn’t work :/

    Thx for you work

    1. Weird. Does it work for customer emails?

  9. Ho Rodolpho ! Just to be sure, this snippet ONLY blocks Customer email for free products, but it does NOT block email sent to admin when a customer orders a free product right ?

    This 2nd option would maybe be useful to avoid receiving hundreds of emails everytime a user ‘buy’ a free product…

    Is that something possible for which I should get a quote please ? ๐Ÿ™‚

    Thanks !

    1. Exactly, Ben! If you’d like to get a quote, feel free to contact me here. Thanks a lot

  10. Thx for the code – but unfortunately, in latest WooCommerce 3.8, woocommerce_email_recipient_customer_processing_order & woocommerce_email_recipient_customer_completed_order hooks are not available anymore.
    Any alternative?

    1. Actually, your code still works. Only had to change the following line. Probably more related to how PHP 7.2 handles float.

      if( $order->get_total() == 0 ) $recipient = '';

      (and found where to look at for the hooks you have used, they still exist – as composite: https://docs.woocommerce.com/wc-apidocs/source-class-WC_Email.html#351)

      1. Excellent, thank you!

  11. Thanks for this code! Do you maybe know how to use a woocommerce custom field email adres as recipient in stead of $recipient = ‘ ‘?
    Thanks in advance!

    1. Hello Mos, 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!

  12. Thank you so much for this snippet, unfortunately it does not work for us.
    We have wordpress 5.1 + Kadeence woocommerce email designer plugin.

    1. Hey Jakub! Does it work if you deactivate email designer?

  13. Thank you for the code <3

    1. You’re welcome Michelle ๐Ÿ™‚

  14. Rodolfo,
    You are a savior. That works so well. But I have another question-

    I want to disable all customer emails in woocommerce (because I want them to be taken care by external application e.g. MailChimp since they offer more control on content customization). However, I want to receive notification on new orders etc. Just wan to disable all customer emails.
    Do you know if there is any easy fix, or a plugin that may do so?

    Thank you so much in advance.

    1. Hello Nick – thanks so much for your comment! Can you not disable them one by one from the WooCommerce > Emails settings?

  15. Hi Rodolfo,
    Is it possible to make the sending of the “customer_new_account” email conditional based on product on order?

    So if product id “123” is part of the order, don’t send the new-account email?

    1. Hi Jason – thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. If you’d like to get a quote, feel free to contact me here. Thanks a lot for your understanding! ~R

  16. I have a question about a somewhat related topic. Because I couldn’t find anything more related on your site I decided to post my question here. Hope that’s OK?

    WooCommerce order numbers are not sequential. I know there is a SkyVerge plugin that takes care of that, but could you provide us with a snippet to fix this?

    1. Hey Steven, that plugin is probably faster than trying to code it ๐Ÿ™‚ Sorry!

  17. Thanks Rodolfo. It works like a charm.
    Is there any simple solution to display just a single line of text instead of the entire WooCommerce table? I have only one (free) product and don’t want to show the default complex Woo table (with Product, Quantity, Price, VAT and such).

    1. Nick, thanks so much for your comment! Yes, this is possible – but unfortunately this is custom work and I cannot provide a complementary solution here via the blog comments. Thanks a lot for your understanding! ~R

  18. What about showing the price as FREE instead of “0”? I have downloadable products so I still need the email to go out but it would be great if it can show FREE instead of “0”.

  19. Thank you, this is just what I was looking for. I can disable a couple of plugins now and improve the full load page perfomance ๐Ÿ˜‰

Questions? Feedback? Customization? Leave your comment now!
_____

If you are writing code, please wrap it like so: [php]code_here[/php]. Failure to complying with this, as well as going off topic or not using the English language will result in comment disapproval. 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 the Business Bloomer Club to get quick WooCommerce support. Thank you!

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