Posted on

WooCommerce: How to Add Content to a Specific Order Email

A client of mine asked me to add some additional text to the thank you page and the customer order email. In both cases, my client wanted to show an immediate upsell to get buyers to go back to the website and buy again with a coupon code.

WooCommerce - how to add content to the order email
WooCommerce – how to add content to the order email

PHP snippet: Add Content to the Customer Processing Order Email – WooCommerce


/**
 * @snippet       Add Content to the Customer Processing Order Email - WooCommerce
 * @how-to        Watch tutorial @ https://businessbloomer.com/?p=19055
 * @sourcecode    https://businessbloomer.com/?p=385
 * @author        Rodolfo Melogli
 * @testedwith    Woo 3.5.1
 * @donate $9     https://businessbloomer.com/bloomer-armada/
 */

add_action( 'woocommerce_email_before_order_table', 'bbloomer_add_content_specific_email', 20, 4 );

function bbloomer_add_content_specific_email( $order, $sent_to_admin, $plain_text, $email ) {
	if ( $email->id == 'customer_processing_order' ) {
		echo '<h2 class="email-upsell-title">Get 20% off</h2><p class="email-upsell-p">Thank you for making this purchase! Come back and use the code "<strong>Back4More</strong>" to receive a 20% discount on your next purchase! Click here to continue shopping.</p>';
	}
}

How to target other Order Emails – WooCommerce

Using the same snippet above, you can target different emails by changing the email ID


if ( $email->id == 'cancelled_order' ) {}
if ( $email->id == 'customer_completed_order' ) {}
if ( $email->id == 'customer_invoice' ) {}
if ( $email->id == 'customer_new_account' ) {}
if ( $email->id == 'customer_note' ) {}
if ( $email->id == 'customer_on_hold_order' ) {}
if ( $email->id == 'customer_refunded_order' ) {}
if ( $email->id == 'customer_reset_password' ) {}
if ( $email->id == 'failed_order' ) {}
if ( $email->id == 'new_order' ) {}

Where to add this code?

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

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.

If you think this code saved you time & money, please join other Business Bloomer supporters and avail of 365 days of WooCommerce benefits. Thank you in advance :)

Need Help with WooCommerce?

Check out these free videos, tutorials and tips!

  • how-to-edit-woocommerce-with-php-snippets
  • woocommerce-hooks-add_action-list-visual
  • woocommerce-customize-single-product-page-PHP
  • woocommerce-customize-shop-page-PHP
  • woocommerce-advanced-customization
  • how-to-edit-woocommerce-cart
  • woocommerce-customize-checkout-page-PHP
  • woocommerce-email-customization
  • woocommerce-conditional-logic

Rodolfo Melogli

Author, WooCommerce expert, WordCamp speaker and Internet marketer, Rodolfo Melogli has worked as a WooCommerce freelancer since 2011. He helps entrepreneurs and developers overcome their WooCommerce nightmares :) Rodolfo is the organiser of WordCamp Dublin, the Dublin WooCommerce Meetup, the Dublin Ecommerce Meetup and the Dublin WordPress Meetup. He enjoys interacting with people, travelling and chasing tennis & soccer balls. Of course, he loves pizza too.

95 thoughts on “WooCommerce: How to Add Content to a Specific Order Email

  1. Hello.
    I tried your snippet and it works great.
    However, I noticed that custom message isn’t added to the email when I create order manually. Don’t you know why?
    Thanks.

    1. Hey Radan, thanks for your comment! What email did you target?

    2. Hi! Sorry for my late answer, but I didn’t get an email notification about your reply, so I thought you haven’t done it. Well, I found out that there’s a problem with some condition which I use further for filtering custom message. I am checking the order payment method, order shipping method and order locale (language). Something from these doesn’t work from the backend as it does from the frontend. I need to do some testing. Wouldn’t you know, how to check order shipping method, cause I think that it could be that issue. Thanks!

    3. Hey Radan, 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

  2. You are a site-safer! With the latest update to WC, my email templates needed updating and doing so now limits the amount of text that I could have in the template. You’re explanation was straight forward and easy to make happen. Thanks for sharing your wealth of information with us.

    1. Thank you Adam, my pleasure ๐Ÿ™‚

  3. Hi Rodolfo i just put this snippet in my theme in functions.php file ,but it doesn’t work, what should be do plz?

    1. Hello Sabrine, I just tested this again with Storefront theme and it works perfectly. Maybe your theme (or another plugin) is messing/conflicting with my snippet?

      To troubleshoot, go to WP Dashboard > WooCommerce > System Status: what errors do you see in red font?

      Also, take a look at this tutorial to see how to troubleshoot: https://businessbloomer.com/woocommerce-troubleshooting-mistakes-to-avoid/

      Finally, can you try switching temporarily to “Twentyseventeen” or “Storefront” theme and let me know if it works?

      Hope this helps!

      R

  4. Hello! This is awesome ๐Ÿ™‚

    I can quite figure this out. How would I simply add the ‘coupon used’ and the ‘coupon details’ below the order table in the ‘processing order’ email?

    Thank you!

    1. add_action( 'woocommerce_email_before_order_table', 'processing_order_mail_message', 20 );
      
      function processing_order_mail_message( $order ) {
          if ( $order-&gt;get_used_coupons() ) 
            echo 'Coupons used in this order are: '; print_r( $order-&gt;get_used_coupons() ); echo '';
      }
      
    2. Great ๐Ÿ™‚

  5. Hi, great work, thanks for this. But I do not know how to address only the order confirmation mail, I do not get the right status, I tried them all – or probably not?

    Thanks for your help.
    Best regards,
    Thomas

    1. Hey Thomas – thanks so much for your comment! “new_order” should work ๐Ÿ™‚

  6. Hi,
    I couldn’t find a solution to my issue here, so I’m hoping you can help out.
    I want my users to be able to create an account during checkout. ( The payment gateway requires an email account before an order can be processed)
    I’ve set this up via Woocommerce settings, however, on the Check Out page it asks the customer to create an account by going to the Registration Page thus truncating the check out journey.
    I would like to avoid this by somehow including user registration form (Name & email address) on the Check Out page.
    Thanks

    1. Hello Lavard – thanks so much for your comment! WooCommerce has a registration form on the Checkout, so you have some other problem (possibly, your theme),. Try switching theme for a moment and see if the form appears ๐Ÿ™‚

  7. Hello, there are various mistakes in the snippet. Should be as follows:

    add_action( ‘woocommerce_email_before_order_table’, ‘bbloomer_add_content_’, 20, 4 );

    function bbloomer_add_content_( $order, $sent_to_admin, $plain_text, $wc_email ) {
    if ( $wc_email->id == ‘customer_processing_order’ ) {
    echo ‘Get 20% off
    Thank you for making this purchase! Come back and use the code “Back4More” to receive a 20% discount on your next purchase! Click here to continue shopping.’;
    }
    }

    1. Thanks for that Amit! Snippet revised and updated ๐Ÿ™‚

  8. I’m racking my brain trying to figure out how to edit this snippet so that I can add a sentence to the Welcome New Customer email.

    I know we can use “customer_new_account” for the email id.
    However the action, we don’t have an order table: “add_action( ‘woocommerce_email_before_order_table ‘) ” I was thinking to add action “before_woocommerce_email_footer” instead of (‘woocommerce_email_before_order_table’)

    What about? This “function add_content( $order, $sent_to_admin, $plain_text, $email )” it’s not an order, so it hasn’t worked for me.

    1. Javier, 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

  9. Thank you!
    But I want to go forward…
    I need grab a field from an Order Tracking plugin to display in the order?
    What are the fields available? Many, for sure, but how I identify them?

    1. Alain, 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

  10. Hello!

    This is great and helpful snippet.
    I have one question please.. I need this snippet to work only on the customer’s complete order emails, not all of them.
    What do i have to add to do this work ?

    Thanks!
    Happy New Year!!!

    1. Hey Kostas, thanks for your comment! I suggest you take a look at “conditional logic”: https://businessbloomer.com/conditional-logic-woocommerce-tutorial/ and https://businessbloomer.com/woocommerce-conditional-logic-ultimate-php-guide/. Let me know ๐Ÿ™‚

  11. This works great! Thank you very much! I have a question: how can I show extra content only for specific shipping methods, e.g. local pickup?
    I tried adding this (from your post Hide Shipping Fields When Local Pickup is Selected):
    $chosen_methods = WC()->session->get( ‘chosen_shipping_methods’ );
    $chosen_shipping_no_ajax = $chosen_methods[0];
    if ( 0 === strpos( $chosen_shipping_no_ajax, ‘local_pickup’ ) ) {
    ….
    }

    but it doesn’t work. On the thank you page the above condition works, it just doesn’t work on emails.

    1. Actually, this is not working on the “Processing Order” email (it works only on the manually-sent “Order Details email). I have Woocommerce 3.2.6. Can you please help out? Thanks!

    2. Hey Yaniv, 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

  12. Thanks for all the great tips.

    I have one question. Is there a way to pull the product ID so that I can use product specific information in the email? I’d like to add the product description in the “woocommerce_email_after_order_table” location of the email.

    1. Hey David, thanks so much for your comment! Of course, you can just declare the global $product, and then echo some info (guide here: https://businessbloomer.com/woocommerce-easily-get-product-info-title-sku-desc-product-object/)

    2. Thanks a lot for all of the help.

    3. Sorry One other question. I am assuming that I am missing something here. Do I need to pull the product ID from the order somehow? What I have below does not work.

      add_action('woocommerce_email_before_order_table', 'add_content', 20, 4 ) ;
      
      function add_content($order, $sent_to_admin, $plain_text, $email) {
      global $product;
      
      	if ( $email->id == 'customer_completed_order' ) {
      	echo $product->get_description();
      	}
      }
      
    4. Hey David, thanks so much for your comment! You can use this reference snippet to access the product IDs inside the $order object: https://businessbloomer.com/woocommerce-check-product-id-order/

  13. Hi Rodolfo,

    Your snippet works great and it’s very useful.

    However, do you know if it’s possible to customize (always via snippet) the default thank-you text. The text “Your order has been received…” just above the text inserted with your snippet.

    I’ve searched a lot but no success

    Thanks.

    1. Hey Daniel, thanks so much for your comment! You can translate that string with this: https://businessbloomer.com/translate-single-string-woocommerce-wordpress/

    2. Thanks a lot!!! Great!!!

  14. Hello, thanks for sharing. Is there a way to add the text coming from a specific page to the Email order footer?
    I mean, I have the page Terms & Conditions on my website that contains all the info. Then, I would like that the text contained in such page was included in the email order footer.
    Is that possible?
    Thanks.
    L.

    1. Ciao Luca ๐Ÿ™‚ 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

  15. Hi, great info like all your blog posts!
    I would like to know if I can restrict this code to past customers only, to prevent abuse. Can this be done?

    1. Hello Felipe, claro! You can check if a user is a customer by checking their user_role. Hope this helps!

  16. Hi Rodolfo,
    Is there a way to add related products to the order processing emails?
    I can’t find a solution anywhere!

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

  17. Thank you a lot for this guide. It works 100%..keep posting!

    1. Thank you so much for your feedback Bhaumik!

  18. You saved my day! Thank you so so so much Rodolfo

    1. Thank you so much Itai!

  19. Hi Rodolfo,

    Very well done!

    I have a request to move the customer details before the order table. Is that possible? If so, how can I move the customer details before the order table.

    Any help would be appreciated.
    Thank you
    Lyse

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

    2. So, even if I have joined your community or if I signup for your courses, this would not be possible to do myself with your guidance? Lyse

    3. Hey Lyse, yes, of course, this is possible ๐Ÿ™‚

  20. I need to add the total discount amount as a row before the “Total” amount row in woocommerce email order table. Please Help!

    1. Hey Neha, thanks so much for your comment! Try to take a look at this other snippet, it should help you a little: https://businessbloomer.com/woocommerce-add-new-row-order-totals-email-thank-page/. Let me know!

  21. Hey Rodolfo,

    do you know how to only include the last order note in the Completed order email?

    Basically, I need the last note that would be the tracking number added to the completed order email.

    Thanks!

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

  22. Can we add products?
    Suggested products will be really cool,am looking for something like this

    1. Of course. Try adding a products shortcode and see if it works ๐Ÿ™‚

  23. Hello there,
    I was wondering if you could help me out. I want to add text ONLY to the order-processing email, and above the footer text(below the customer details). I tried this

    
    // add text to the thank you page
       
    add_action( 'woocommerce_email_footer($email)', 'add_content' );
       
    function add_content($email) {
      
    // Adds to "processing order" email only
    if ( $email-&gt;id == 'customer_processing_order' ) {
      
    echo '&lt;My text';
    }
    }
    
    

    but it’s not working…
    Thank you greatly for your help.

    1. Hello Manu, thank you very much for our comment! Yes, your code wouldn’t work. However, I covered this a few weeks ago in our free WooCommerce class and you can watch the video here: https://businessbloomer.com/customize-emails-woocommerce/. Let me know if that helps ๐Ÿ™‚

    2. Hello Rodolfo,
      thank you for your quick reply. I actually got it to wokr by overriding the template in my child theme – I know it’s better to use a function, but I needed to add a lot of different custom text based on payment types anyway, so I just hope Woocommerce is not going to update these files a million times ๐Ÿ˜‰

      But I actually have another problem that I just can’t get resolved: I made a few css tweaks in the email-styles.php in my child theme. Certain things are just not getting applied though, even with !important. Can you help me

      a) how to totally remove/hide the “subtotal” row in the order table?
      b) how to change the font family of the td.td row for the product, quantity and price( the first td row underneath the table head)?

      Again, I greatly appreciate your help!
      Manu

    3. Rodolfo,
      the problem ist that I think I have the correct selector but it’s not working! I have my own email-styles.php in my child theme and successfully changed many styles in it, but these two things are just not getting applied!

    4. Not sure, almost impossible to help without having access to your website files ๐Ÿ™‚ Sorry!

    5. Hi Rodolfo, I got a) to work and regarding b): I found ou the style for this is not set in email-styles.php, but in email-order-items.php…would you know how to hook in this rather than overriding this particular template? Thank you ๐Ÿ™‚

  24. Hello Rodolfo,

    Thanks a lot for these materials, they are really awesome!

    Currently, I am trying to hide/remove some Order details from all Woocommerce emails. These details are coming from a plugin for custom printed products (they are shown below the Product details) and are not relevant for the customer. You can see a screenshot with them in the following link: https://www.dropbox.com/s/gyj2egwe2nug4qk/Screenshot.png?dl=0

    May I ask you which Snippet can solve this?

    Thank you very much for your help, any insight you can give me will be highly appreciated.

    Carlos

    1. Hello Carlos, thanks for your comment! I’m afraid I can’t help with third party plugins, so I’m not sure. You’d need to investigate the PHP code that “injects” this extra info in the emails and disable it.

      Otherwise you can try with the lazy way of adding display:none via CSS: https://businessbloomer.com/woocommerce-add-css-woocommerce-emails/

      Good luck ๐Ÿ™‚

    2. Thanks Rodolfo! I really appreciate your advice.

      I’ll keep you post on how it worked out.

    3. Thank you! ๐Ÿ™‚

  25. Why this is not working, if I only want to edit the Completed Order template? Where exactly to look for what works, what doesn’t?

     
    // add text to the thank you page
     
    add_action( 'woocommerce_email_before_order_table', 'add_content', 20 );
     
    function add_content($email) {
    
    // Adds to "completed order" email only
    if ( $email->id == 'customer_completed_order' ) {
    
    echo '<h2 id="h2thanks">Get 20% off</h2><p id="pthanks">Thank you for making this purchase! Come back and use the code "<strong>Back4More</strong>" to receive a 20% discount on your next purchase! Click here to continue shopping.</p>';
    }
    }
    
    1. Hey Swapii,

      Thanks for your comment!

      The “woocommerce_email_before_order_table” hook takes 4 parameters (see my visual hook guide at http://businessbloomer.com/woocommerce-visual-hook-guide-emails). Therefore, your function should have all those parameters if you’re willing to use $email:

      
      function add_content($order, $sent_to_admin, $plain_text, $email) {
      
      

      Let me know ๐Ÿ™‚

    2. Thank you, Rodolfo, but it doesn’t work as well. ๐Ÿ™

    3. Uhm, I forgot to say that if you add those 4 variables inside the function, you also need to add a “,4” here at the end before the closing bracket:

      add_action( 'woocommerce_email_before_order_table', 'add_content', 20, 4 );
      

      Let me know ๐Ÿ™‚

    4. Yes, thank you, this works. ๐Ÿ™‚

      // add text to the thank you page
        
      add_action( 'woocommerce_email_before_order_table', 'add_content', 20, 4 );
        
      function add_content($email) {
       
      // Adds to "completed order" email only
      if ( $email->id == 'customer_completed_order' ) {
       
      echo '<h2 id="h2thanks">Get 20% off</h2><p id="pthanks">Thank you for making this purchase! Come back and use the code "<strong>Back4More</strong>" to receive a 20% discount on your next purchase! Click here to continue shopping.</p>';
      }
      }
      
    5. Excellent ๐Ÿ™‚

  26. Very helpful, thank you! Is there a way to only add it to the ‘Complete’ order email? When I add it to functions.php it displays in ‘Invoice’, ‘Processing’ and more. Is these ‘Processing’ email also editable separately?

    1. Jeffrey, thanks for your comment! This is indeed possible, and it’s not too difficult – in July I will run a class on how to customize Woocommerce emails (http://businessbloomer.com/customize-emails-woocommerce/) so I guess this is perfect timing! Hope to “meet” you online ๐Ÿ™‚

  27. Thanks Rodolfo Melogli,

    Your code is very use full for me. It’s work great. Good job. ๐Ÿ™‚

    Ketan

    1. Thank you so much Ketan ๐Ÿ™‚

  28. I wonder, what sort of filter would I use if I wanted to use that snippet [and others] to specific products?

    1. Hey Navot, thanks so much for your comment ๐Ÿ™‚

      You would use the same filter, but inside the function you should use a check to see what product is in the order.

      Unfortunately I can’t cover this in this blog right now but I will put it on my to-do list for the next months ๐Ÿ™‚

      Thank you!

  29. Hi Rodolfo,
    May I know if I can do likewise on the customer invoice mail?
    I noticed the customer invoice mail doesn’t include shipping cost, any way I could include that in the table of customer invoice?

    Thanks!

    1. Lee, this works on the customer invoice email as well ๐Ÿ™‚

  30. Is there a way to show this text on the order email only if the customer (logged in or not) has not bought anything before? I found this code online but can’t figure out a way to incorporate it. The is_user_logged_in doesn’t seem to work.

    http://stackoverflow.com/questions/31267673/woocommerce-check-if-customer-has-made-more-than-a-certain-number-of-orders-or

    1. Vuster, thanks so much for your feedback! Yes, this is possible – but unfortunately it’s pretty custom and I cannot provide this solution on the blog. If you would like to get a quote, feel free to go here. Thank you! R

  31. Isn’t the hyperlink missing in the “Click here” part of the code?

    1. Of course Vu ๐Ÿ™‚ You can add whatever HTML you like inside that function. R

  32. Hi Rodolfo,
    I came here from a google search.
    I would like to know how to show product full description (not the short description) in the shopping cart and the Order email sent to Admin.
    I have a child AVADA theme with the woocommerce folder.
    regards
    Maximoau

    1. Maximoau, thanks so much for your feedback. Take a look at this post, you will find a function to show the Short Description (excerpt). If you want to show the Long Description, just use the_content(); instead of the_excerpt();

      Hope this helps ๐Ÿ™‚

  33. Hey,

    These are great tips. You havent mentioned which file to edit anywhere though… It would be great if you mentioned the file where these lines of code need to be added. Thanks

    1. Thank you! You can add them to your template’s functions.php file ๐Ÿ™‚

    2. Thanks a lot for this Rodolfo, very helpful. Is the code added to my ‘themes’ functions.php file, rather than my ‘templates’?

    3. Absolutely! Always, always, in the functions.php of your child theme ๐Ÿ™‚ Thanks for sharing your feedback Noelle!

    4. Thanks a mil!

    5. You’re welcome! And happy St. Patrick’s Day ๐Ÿ™‚

Questions? Feedback? Support? Leave your Comment Now!
If you're writing code, please wrap it between: [php] code_here [/php]

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.