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 showing an upsell to get buyers to go back to the website and buy with a coupon code. Enjoy!

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

PHP Snippet: Add Content to the WooCommerce Customer Processing Order Email

/**
 * @snippet       Add Text to Customer Processing Order Email
 * @how-to        businessbloomer.com/woocommerce-customization
 * @author        Rodolfo Melogli, Business Bloomer
 * @testedwith    Woo 4.6
 * @community     https://businessbloomer.com/club/
 */
 
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 WooCommerce Order Emails

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 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

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

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

  1. Hi, I added the snippet to target customer new account email but is not working.

    
    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-&gt;id == 'customer_new_account' ) {
          echo 'Instala nuestra AppPara una mejor experienca instala nuesta app siguiente estos pasos.';
       }
    }
    
    
    1. The problem could be that HTML “gt” symbol. Try changing it to “->”

  2. Hi,
    Thank you for providing this excellent snippet. I’m using the following code to add a My Account link in the email. However, I need to only show this if the customer has created an account and not for Guest customers. Is this possible?

    /**
     * Add My Account details to Customer Processing Order Email
     */
      
    add_action( 'woocommerce_email_after_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 '<p class="email-upsell-p">You can view your orders by logging into your account here: <a href="https://domain.co.uk/my-account">My Account</a></p>';
       }
    }
    

    Thanks.

    1. Hi Andrew, 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 Rodolfo, I want to change text string for Order : #761 to Booking :#761, how should I do that? Thanks

  4. Obrigado Rodolfo!
    Your snippets are wonderful!
    What would this code look like, if I want to have a personalized message, just for a product ID?

    Thank You

    1. Hey Josè thanks for your message! I suggest you take a look at “conditional logic”: https://businessbloomer.com/woocommerce-conditional-logic-ultimate-php-guide/. Enjoy 🙂

  5. Hi Rodolfo,

    Just a message to thank you, I follow you regularly, you’re the best, thanks so much.

    Ps: I hope to ask your help for a custom development soon.

    Have a nice day

    Kevin

  6. Hi Rodolfo,

    How can I add a custom order field to email?
    I’m trying to add tracking url to completed order email, but it isn’t working properly.

    add_action( 'woocommerce_email_before_order_table', 'track_shipment_order_completed_email', 20, 4 );
      
    function track_shipment_order_completed_email( $order, $sent_to_admin, $plain_text, $email ) {
       if ( $email->id == 'customer_completed_order' ) {
          echo '<p class="btn-container"><a href="'. get_post_meta( $order->id, "_track_url_meta", true ) .'">Śledź przesyłkę</a></p>';
       }
    }
    1. Should be $order->get_id()?

  7. Hi Rodolpho,

    Would it be possible to add the PayPal fees amount to order emails since they’re now displayed in Woocommerce please ?

    Been looking around but not even sure it’s doable with php.

    1. Hello Ben, 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. Hey,
    I am trying to add your code but get an error: ‘Something went wrong. Your change may not have been saved. Please try again. There is also a chance that you may need to manually fix and upload the file over FTP.’

    1. Please use FTP to edit your child theme and not the WordPress editor

  9. Hi there,

    Your site is SUPER useful, your blogs help me a lot for years, and this is my first comment.

    In the woocommerce emails, there is a price column. Is that possible to replace the $0.00 to “Free” in the email?
    Also, if subtotal and total is $0, is that possible to hide them from the emails?
    If products are not $0 everything should remain the same like default.

    Thanks

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

  10. Can anyone help me I’m just a beginner, what should I fix in this code???

    add_action( 'woocommerce_email_before_order_table', 'bbloomer_add_content_specific_email', 20, 4 );
    function woocommerce_custom_email_per_product_depending_on_product_id( $order, $sent_to_admin, $plain_text, $email ) {
        global $woocommerce;
        $items = $order-&gt;get_items();
        foreach ( $items as $item ) {
            $product_id = $item['product_id'];
            if ( $product_id == 5069 ) {
          echo 'Get 20% offThank 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.';
       }
        }
    }
    
    1. Your add_action function name is wrong

      1. Hi Rodolfo I am a WordPress developer as well
        Was just Wondering why he declared global woocommerce when $woocommerce is never used in the action hook function??

        1. Indeed, it can be removed

  11. hi!
    love your site 🙂
    is it possible to use this code to show the custom text only if order total (without backorders) is above 100?

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

  12. Hello,
    is it possible to make an extra information in e-mail when product is out of stock (and can be backordered)?

    1. Hi Matt, 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. Hi Rudolfo,
    thanks for your tutorials! I have added a snippet to the functions.php field to add a “More Products” section to the order emails but it is not working anymore since the latest WC and WP updates. Do you have any idea why it isn’t working anymore and how to fix this? Thank you!
    This is the rather long code:

    // Product suggestions in order invoice mail
    function order_mail_product_suggestion($atts) {
        $atts=shortcode_atts(
            array(
                'id' => '',
            ), $atts, 'order_mail_product_suggestion');
        $orderId = esc_attr($atts['id']);
        $order = wc_get_order( (int)$orderId );
        $items = $order->get_items();
        $cat = array();
        $pid = array();
        foreach ( $items as $item ) {
            $pid[] = $item->get_product_id();
            $terms = wp_get_post_terms($item->get_product_id(),'product_cat',array('fields'=>'ids'));
            foreach ( $terms as $term ) {
                $cat[] = $term;
            }
        }
        $uniuqcat = array_unique($cat);
        $uniuqpid = array_unique($pid);
        $html = '';
        $args = array(
            'post_type'             => 'product',
            'stock'                 => 1,
            'post_status'           => 'publish',
            'ignore_sticky_posts'   => 1,
            'posts_per_page'        => '20',
            'tax_query'             => array(
                array(
                    'taxonomy'      => 'product_cat',
                    'field' => 'term_id',
                    'terms'         => implode(',', $uniuqcat),
                    'operator'      => 'IN'
                ),
                array(
                    'taxonomy'      => 'product_visibility',
                    'field'         => 'slug',
                    'terms'         => 'exclude-from-catalog',
                    'operator'      => 'NOT IN'
                )
            )
        );
        $loop = new WC_Product_Query($args);
        $products = $loop->get_products();
        if ($products) {
            $html .= '<div id="suggestion" style="padding: 20px 0;border-top: 1px solid #eee;">';
                $html .= '<h2 style="text-align: center;font-weight: 400;color: #000;">MORE PRODUCTS YOU MAY LIKE</h2>';
                $html .= '<table style="width: 100%;table-layout: fixed;border-collapse: collapse;">';
                    $html .= '<tbody>';
                        $html .= '<tr>';
                                $i=0;
                                foreach ( $products as $product ) {
                                    if (in_array($product->get_id(), $pid)) {
                                        continue;
                                    }
                                    $html .= '<td align="center" style="padding: 5px;border: 1px solid #eee;">';
                                    if (has_post_thumbnail( $product->get_id() )) {
                                        $html .= get_the_post_thumbnail($product->get_id(), 'shop_catalog');
                                    } else {
                                        $html .= '<img src="'.woocommerce_placeholder_img_src().'" alt="Placeholder" width="300px" height="300px" />';
                                    }
                                    $html .= '<h3><a style="color: #000;font-weight: normal;text-decoration: none;font-size: 13px;text-align: center;display: block;line-height: 16px;" href="'.get_permalink( $product->get_id() ).'">'.esc_attr($product->get_title() ? $product->get_title() : $product->get_id()).'</a></h3>';
                                    $html .= '<p><a style="font-weight: normal;text-decoration: none;display: block;margin: 0 auto;max-width: 72px;padding: 4px 9px;text-align: center;background-color: #000;color: #fff;font-size: 13px;" href="'.get_permalink( $product->get_id() ).'" class="shop-now">Shop Now</a></p>';
                                    $i++;
                                    if($i==4) break;
                                }
                        $html .= '</tr>';
                    $html .= '</tbody>';
                $html .= '</table>';
            $html .= '</div>';
        }
        // now return the preapred html
        return $html;
    }
    
    // register shortcode
    add_shortcode('email_product_suggestion', 'order_mail_product_suggestion');
    
    1. Sorry, can’t help with custom troubleshooting. How do you add the shortcode to the emails?

  14. I need some line breaks in my message. Tried variants of \n and , but didn’t succeed. Could you give me a hint?

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

  15. What would be the best way to add the same message to several emails?

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

  16. I did not understand how I create this change in the email for “failed order” – I want a customer whose order failed to receive an email with the caption “Your order failed, you can return to it” or something like that, how to do it
    Thank you so much for the great guides

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

  17. Hi Rodolfo, i made a custom email template for “new order” , did you how to make it only for specific category ?

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

  18. Help i want to show product “PRODUCT NAME” was sold email subject admin-new-order php file

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

  19. Hi Rodolfo,

    Thank you so much for your great tutorials.
    What do I have to add in this snippet to add text only when the order include a specific product?

    Thank you in advance for your help.
    Valentin

  20. Hi Rodolfo! As usual wonderful tutorial!
    Beside adding more info to customer emails, I’m trying also to remove the payment instructions from all customer email notifications (except the customer_processing_order email), for Direct Bank Transfer (BACS).

    To remove the ‘woocommerce_email_before_order_table’ action I’m doing this:

    $gateways  = WC_Payment_Gateways::instance(); 
    $available_gateways = $gateways->get_available_payment_gateways();
    	
    remove_action( 'woocommerce_email_before_order_table', array( $available_gateways['bacs'], 'email_instructions' ),  10,  3 );
    

    I don’t know what am I doing wrong here. Could you please provide some guidance?
    Thank you
    Valdinia

    1. After posting the question I realized what I did wrong.
      Beside adding more info to customer emails I was also trying to remove the payment instructions from some of the emails, so the priority of my function should be a lower number, to be executed earlier:
      add_action( ‘woocommerce_email_before_order_table’, ‘cde_customize_content_for_specific_emails’, 1, 4) ;

      1. Nice

  21. Hi,

    Is there a way to change the greeting text of all emails of woocommerce from:

    1. <p><?php printf( esc_html__( 'Hi%s,', 'woocommerce' ), esc_html( $order->get_billing_first_name() ) ); ?></p>

      to

      <p><?php printf( esc_html__( 'Dear %s,', 'woocommerce' ), esc_html( $order->get_billing_first_name() ) ); ?></p>

      without the need to copy the email files under child theme? Perhaps using a hook?> If that’s possible, can i have the example please?

      Thank you so much in advcance

  22. Hi Rodolfo,

    My customer wants to add the Woocommerce Membership Number to the order email that they receive, i.e. the New Order email. Or just have some indication of whether the order is from a member or non-member. Any ideas on whether this can be accomplished?

    Thanks!

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

  23. Rodolfo,

    Below is a copy of your php code “Add Content to the Customer Processing Order Email” . I would like to add a custom message to emails wwith products that are backordered. Is there a way to select customer emails with backordered products add the custom message (perhaps using your code below)?

    Thank You Kindly

    Matt

    /**
     * @snippet       Add Content to the Customer Processing Order Email - WooCommerce
     * @how-to        businessbloomer.com/woocommerce-customization
     * @author        Rodolfo Melogli, Business Bloomer
     * @testedwith    Woo 3.8
     * @community     https://businessbloomer.com/club/
     */
      
    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>';
       }
    }
    1. Hi Matt, thanks so much for your comment! Yes, this is definitely possible (you’ll need to loop through $order to find order items and see if they’re backordered), 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!

  24. Hello,
    I want to replace following text from mail which received after the payment of the order:

    Your order has been received and is now being processed. Your order details are shown below for your reference:

    Is it possible to do using above code in functions.php?

    Thanks in advance.

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

  25. will this work with woocommerce subscriptions plugin for activation/deactivation emails?

    1. It should – you need to find the custom email ID in that case

  26. Works great. Thank you for the snippet.

    1. Great!

  27. add_action( 'woocommerce_email_after_order_table', 'bbloomer_add_content_specific_email' );
    function bbloomer_add_content_specific_email( $order, $sent_to_admin, $plain_text, $email ) {
      //
    }
    

    Gives me “Internal server error”, while this works fine:

    add_action( 'woocommerce_email_after_order_table', 'bbloomer_add_content_specific_email' );
    function bbloomer_add_content_specific_email( $order ) {
      //
    }
    
    1. You forgot the very important “4” inside the add_action call

      1. Oh… Yep, it works now 🙂 Hmm, interesting…

        1. Great 🙂 That number must be equal to the number of variables you declare inside the function. By default if omitted it’s equal to 1, so this is why it was working in the second example you gave me 🙂

          1. Wow! Really, I’ve never used this parameter, only the one for priority sometimes, thanks for the explanation! 🙂

            1. Great!

  28. This snippet does not work since WooCommerce 5.8 any more. I tested it on two websites. Do you have any idea why it does not work anymore?

    1. Works perfectly for me on 3.8!

      1. Okay, I found another error which occurred and affected your code snippet. Sorry! The code snippet is still on work with WooCommerce 3.8 and up. I’m sorry!

        1. No problem!

  29. add_action( 'woocommerce_email_after_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 == 'new_order' ) {
          echo '<h4 style="color:red; "> Delivery Charges Extra</h4>';
       }
    };
    

    after adding the above function in functions.php, admin able to receive order email with the custom content but customer not receiving the content

    1. This should only generate extra content for the “New Order” email, which only goes to the admin

  30. Hi there,
    I want to send an extra email to vendor as well on creation of new order.
    Can you please help me out here

    Thank you

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

  31. Excellent pointers!

    I’m assuming this can be used to address emails from the WooCommerce extensions as well. I cannot seem to find a reference anywhere what the names are for the emails that originate from WooCommerce Teams. I’m very keen to modify the team invitation email and I think all I’m missing is the name of the email so I can update the if-clause accordingly.

    Thanks in advance.

    1. Not sure Johan, try asking their support teams

  32. Hi Rodolfo,
    I’m beginning to be addicted to your website. Great advice all around.
    I was just using the useful tip on using the woocommerce_email_before_order_table hook and I bumped into a weird problem.
    Everything from your tutorial works fine (custom text gets added before or after the content table) until the moment I add a hyperlink to the appended text. If I do – the customer_completed_order won’t get send at all. Using other HTML tags like strong and em doesn’t seem to have any adverse effect on the process – just the hyperlinks (a)!
    I noticed that your demo script also doesn’t have the “click here” anchor in it.
    At the moment the error log is clean and I’ve run out of ideas how to fix the issue.
    Any suggestions will greatly appreciated.
    Once again thank you this fantastic resource!
    Best,
    Jack

    1. Hi Jack, can you paste your code here?

  33. Hi, Rodolfo!
    I’m junior in WP, specially in WooCom, so I really hope for your help 🙂
    I’m trying to make some condition for ‘customer_processing_order’ email template, I would like to make some paragraph after footer.
    My code looks like that:
    id == ‘customer_processing_order’ ) :?>

    ……..

    But it doesn’t work in customer_processing_order mail. What’s wrong?

    1. <?php if ( $email->id == 'customer_processing_order' ) :?>
       <tr>
      ...
       <tr>
      <?php endif; ?>
      
      1. Not sure Alex, I’d need to look at the whole code and not only this section to get an idea

  34. Hello.

    Thank you for this helpful snippet.
    I was wondering if i can use it in two diffrent order status at the same time.
    If this can be done, can you show me how ?

    Thanks
    Kostas

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

  35. Hey Rodolfo,
    First of all thank for this unique and amazing website its truly amazing.
    Could you please make a video showing how do you approach the woo docs they are very somewhat not clear.
    for example :
    1. how do you know what is a hook or a filter, what parameters do you have on each one etc, because the docs are very confusing. and most of the time for me I don’t know where to start.
    2. more over do you have any tips on how you can see all the parameters output of action/filter/function using print_r or something similar , so you can reverse engineer what you have to work with ?

    Thanks a a lot.

    1. Hello Osh, the new version of #CustomizeWoo Online Course should help you do just that: https://customizewoo.com

  36. Thanks for the snippit and knowledge! It works great with WordPress 5.1.1 and Woocommerce 3.6.1.

    1. Great!

  37. Where is the “click here” to continue shopping link? I can’t see it in the code….

    1. Hello Louise, you can just add an “ahref” link inside the HTML:

      <a href="your_url">click here</a>
  38. Thank you very much for the code! And thank you very much for all the tips of your blog!
    I have a question, I would like the coupon to be the value of a custom field. I give you an example of the code that I would like it to work but that I have not managed to work well, only the formula appears and not the value of the field.

    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-&gt;id == 'customer_processing_order' ) {
            echo 'Get 20% offThank you for making this purchase! Come back and use the code "<strong>$ order -&gt; get_shipping_address_2 ()</strong>" to receive a 20% discount on your next purchase! Click here to continue shopping.';
        }
    }
    1. Carlos, 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. You could also just create a link with a URL coupon.

      Reference: https://docs.woocommerce.com/document/url-coupons/

  39. Hello, please l am trying to send confirmation email to client after successful checkout in woocommerce with all travelers name list on the confirmation email. please help. Thanks

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

  40. Hi Rodolfo,

    I added successfully a few lines in my “order complete” email.
    But since I do downloads, the email has a download table and a order table.

    The text does go before Order Table, but I would like it even before the Download table (which is before order table as well).

    Any tips?
    Roelof

  41. Perfect – Thanks

    1. Glad it helped!

  42. Hi! I need to add text like this to our e-mails, but it need it to be in different languages depending on (from) where the order was placed (we currently have 2 versions of our site/shop through the WPML translation plugin).
    How can we make 2 language versions of this text?
    Thanks!

    1. Hello Justin, thanks so much for your comment! Yes, this is possible – 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

  43. hello how can I add css code.

  44. Hi!

    I was using this code. And after several testing I found out that my page cannot redirect to order received page (after payment) because of this code. I am not using storefront theme, I’m not sure if others experience the same?

    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_completed_order' ) {
            echo '<p>You may track your order <a href="https://www.aftership.com/couriers/korea-post">here</a></p>';
        }
    1. Hey Manhua, thanks so much for your comment! I just retested this on the latest version of WooCommerce and it still works. Unfortunately this looks like custom troubleshooting work and I cannot help here via the blog comments. Thanks a lot for your understanding! ~R

  45. 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!

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

  46. 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 🙂

  47. 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

  48. 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 '';
      }
      
      1. Great 🙂

  49. 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 🙂

  50. 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 🙂

  51. 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 🙂

  52. 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

  53. 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

  54. 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!!!

  55. 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!

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

  56. 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();
      	}
      }
      
      1. 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/

  57. 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!!!

  58. 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

  59. 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!

  60. 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

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

    1. Thank you so much for your feedback Bhaumik!

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

    1. Thank you so much Itai!

  63. 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

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

        1. Hey Lyse, yes, of course, this is possible 🙂

  64. 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!

  65. 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

  66. 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 🙂

  67. 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 🙂

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

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

            1. Not sure, almost impossible to help without having access to your website files 🙂 Sorry!

              1. 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 🙂

  68. 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 🙂

      1. Thanks Rodolfo! I really appreciate your advice.

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

  69. 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 https://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 🙂

      1. Thank you, Rodolfo, but it doesn’t work as well. 🙁

        1. 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 🙂

          1. 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>';
            }
            }
            
  70. 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 (https://businessbloomer.com/customize-emails-woocommerce/) so I guess this is perfect timing! Hope to “meet” you online 🙂

  71. Thanks Rodolfo Melogli,

    Your code is very use full for me. It’s work great. Good job. 🙂

    Ketan

    1. Thank you so much Ketan 🙂

  72. 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!

  73. 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 🙂

  74. 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.

    https://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

  75. 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

  76. 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 🙂

  77. 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 🙂

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

        1. Absolutely! Always, always, in the functions.php of your child theme 🙂 Thanks for sharing your feedback Noelle!

          1. Thanks a mil!

            1. You’re welcome! And happy St. Patrick’s Day 🙂

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 *