Search the site:

Home Blog How to Create Custom Email Templates in WooCommerce

How to Create Custom Email Templates in WooCommerce

Ever wondered how to create a custom email template that is visible in WooCommerce->Settings->Emails and can be managed and customized the same way as all other WooCommerce emails?

This post will guide you through WooCommerce’s inbuilt email templates structure & also understand how to create custom email templates in WooCommerce.

This can be done very easily using 2 WooCommerce email classes, WC_Emails and WC_Email. These are the 2 main email classes. The WC_Emails class is present in woocommerce/includes/class-wc-emails.php. The WC_Email class is present in woocommerce/includes/emails/class-wc-email.php.

Apart from these they have email classes for each of the emails and the templates as well. Some of the email classes present are class-wc-email-new-order.php, class-wc-email-failed-order.php and so on. All of these email classes are present in woocommerce/includes/emails/ folder.

The templates for these are present in woocommerce/templates/emails/ folder. The html templates are present in the folder itself, whereas the plain text templates are present in woocommerce/templates/emails/plain/ folder.

WC_Emails sends all the transactional emails. It loads all the available emails to be sent out when triggered (yes, we need to write those triggers for our custom emails!).

The WC_Email class is the one which is extended by each of the email template classes to add emails to WooCommerce. This is the class which helps us configure all the emails provided by WooCommerce.

It lists the emails in the Email Notifications page in WooCommerce->Settings->Emails.

Email Notifications
Email Notifications

The emails can be configured by clicking on the email title.

The above is the page where we can configure the settings for the New Order email, which is sent to the admin when a new order comes through.

When we create a custom email that extends the WooCommerce classes, we also are able to take advantage of all the WooCommerce email features.

The advantages of extending these WooCommerce classes and their functionality are many. Such as:

  1. It allows your users to easily enable/disable the email template (You don’t need to provide any additional setting for the same).
  2. Users can add, edit recipients as desired.
  3. It can be customized the same way as any other WooCommerce email (so you don’t have to teach them how to do it 🙂 )
  4. You don’t need to write any css for the emails. Since they inherit the WooCommerce class, you just need to create the email content.

Here are the different components of a custom email that must be configured for it to be sent:

  1. Creating an email manager file.
    1. It will add the custom email trigger/s.
    2. It will queue up the custom email class.
  2. Creating the email class file.
    1. It will be a custom class which extends the WC_Email class.
    2. It will contain details like the ID, title etc.
    3. A list of the fields that will help the user configure the email like recipient, email subject, email heading and so on.
    4. Some functions related to sending the email (like getting the template, email subject and so on).
  3. The email templates. It is advisable to have 2 email templates.
    1. An HTML template.
    2. A plain text template.

In the below example, we will create a new custom email that will be sent to the admin for each item in an order, when the order status is changed to Pending Payment.

Step 1. Creating the Email Manager

The first thing that you need to do is create an email manager class. This class would queue up all your custom emails in the WooCommerce email queue. So in our case, it will queue up the pending payment notification email.

It can be created as a single file in the plugin for which you are trying to add a custom email. In a scenario where you are trying to add a custom email for a WooCommerce functionality, it is advisable to put the custom email files in a stand alone plugin.

We need to use the filter woocommerce_email_classes to include our email classes.

We also need to queue up our email triggers here. This has been done in the construct itself.

The email actions are triggered using the add_action for each value in the $email_actions array where we hook into the send_transactional_email function from the WC_Email class.

So in our case, custom_pending_email and custom_item_email are the email triggers. The custom_pending_email will be triggered when an order status is changed. We pass the Order ID in here. The function attached to this hook is in class-custom-email.php file. This function then gets the Item ID for all the items in the order and triggers the custom_item_email hook for each of the items.

The filter woocommerce_template_directory is a part of the WC_Email class. It is run when trying to get the template from the theme. Hence, we need to make sure we pass the correct directory name as needed.

Step 2. Creating the Email class

Next, create an email class for each of your custom emails. This class will extend the WC_Email class.

Since, we have only 1 custom email, we will create only 1 email class class-custom-email.php. Following the WooCommerce structure it is advisable to create the email class file in the /emails/ folder of your plugin.

The construct contains data like ID, title, description, heading and so on. It also contains a path to the template files.

We need to rewrite the below functions:

  1. get_content_html() – This function will get the html email template.
  2. get_content_plain() – This function will get the plain text email template.
  3. get_subject() – will return the email subject.
  4. get_heading() – will return the email heading.
  5. init_form_fields() – This function defines the fields which will be displayed in WooCommerce->Settings->Emails for the custom email.

We then need to attach functions to our email triggers. For e.g. our email actions are custom_pending_email and custom_item_email. So, in this class, we will attach functions to those.

The queue_notification function loops through all the items in an order and for each item triggers the custom_item_email event. This in turn will call the trigger function for each item.

We shall also create an object of the data that we need to pass to our email templates. This object will contain the item data in our case. It can hold any data as needed for the email.

As mentioned I’m going to send a custom email to the admin for each item in an order when the order status changes to pending. So the object that I create will contain basic details like order id, product ID, product name, quantity and the amount.

We have passed this object to the template in the get_content_html() and get_content_plain() functions.

Once the email class file is created, the email will be listed in WooCommerce->Settings->Emails.

Create Custom Email Templates in WooCommerce - Email listed in WooCommerce->Settings->Emails
Email listed in WooCommerce->Settings->Emails

The email settings can easily be edited by clicking on the email title.

Create Custom Email Templates in WooCommerce - Edit Email
Edit Email

Step 3. Creating the Email Templates

You will need to create 2 email templates: HTML & plain text template. Following the WooCommerce template structure, I usually create all my email templates in templates/emails/ folder of my plugins.

As you can see below, my email templates contain basic information about the product like product name, quantity and amount. Details as desired can be added in here.

HTML template.

Plain text template.

Finally add your email action triggers. I have added the trigger in the custom-email-manager.php file itself. The hook woocommerce_order_status_pending is triggered when an order status changes to Pending Payment.

In the function attached to the hook, we add a do_action for our email action i.e. custom_pending_email.

This is all that we need to do. This will send an email to the admin for each item in an order when the order status changes to Pending Payment.

Email sent when an order status is changed to Pending Payment.

Create Custom Email Templates in WooCommerce - Email Sent
Email Sent

A quick recap of which files do what:

  1. The email manager class queues up and triggers your emails to be sent by WooCommerce.
  2. The email class file adds your email in WooCommerce->Settings->Emails and also allows the user to easily manage the same.
  3. The email templates are used for creating the email content.

I have used this approach to create the emails that are sent by the Booking & Appointment Plugin for WooCommerce.

The plugin sends 4 different emails for different functionalities.

Create Custom Email Templates in WooCommerce - Booking & Appointment plugin emails

Originally I had 3 emails for the Requires Confirmation feature. Later when we decided to make the plugin compatible with 2 way Google Calendar sync, the need for another email template arose. That’s when I fully realized the ease of using WooCommerce to create our custom emails. All that I had to do was add an extra email class, create the templates and we were ready to go!

Once the email manager is setup, it’s just a matter of adding more email triggers, classes and templates. You can add as many custom emails as needed.

Do let me know in the comments if this post helps you create your custom emails the WooCommerce way!

Browse more in: Code Snippets, WooCommerce How Tos, WooCommerce Tutorials

Leave a Reply

14 Comment threads
27 Thread replies
Most reacted comment
Hottest comment thread
20 Comment authors
LeSScroFrancesco SalaKoolPalJamesenola Recent comment authors

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

newest oldest
Notify of

Hi, this tutorial looks very great but i have an issue.. I can’t find my new template in woocommerce->settings-> emails. I think i didn’t put files in the right place. Could you be more specific please ? Especially about the manager..
Thank you


I just solved the issue. I just changed the ” include_once( ‘includes/emails/class-custom-email.php’ )” line 37 of my custom-email manager to make the same path as woocommerce does

Vishal Kothari

@magsen, Apologies for the late reply. I am glad you were able to solve the issue by changing the path.

Usha Kalamani
Usha Kalamani

Hi where to place the custom-email-manager.php file.
Thank you


I’ll be trying this out to send custom emails for virtual products and to differentiate the emails sent for physical products.

I will also try to use this for review reminder emails using wp Cron. I’ll let you know how it goes. Thanks for creating such an informative document.

Vishal Kothari

@Phil, That’s a great use case. Let me know how this goes. It would be nice to see this in action.


Hi Vishal,
I’m still working on it, but I’ll keep you posted once I get it working.

Vishal Kothari


Usha Kalamani
Usha Kalamani

Hi where to place the custom-email-manager.php file.
Thank you


Thank you for the tutorial! I ran into an issue where emails were being duplicated.

The solution was to replace this line:

new WC_Emails();

with this:


The reason being, each time you create a new instance of the WC_Emails class it will re-run the hooks (thus duplicating any pending emails).


Thank you Torrelasley for your suggestion. It fixed strangely nested (standard WooCommerce) emails for me when I tried to trigger at woocommerce_order_status_processing instead of woocommerce_order_status_pending.


Thanks!! Finally a script that fully works!

One question, how can I modify the script so that the e-mail is being sent when the order changes to ‘Processing’? I tried changing ‘add_action( ‘woocommerce_order_status_pending’, array( &$this, ‘custom_trigger_email_action’ ), 10, 2 );’ by changing pending into processing, but that doesn’t work.

Looking forward to your reply!



Priyanka Jagtap
Priyanka Jagtap

Hi Max,

I apologize for the delay in response.

I am glad to know that the above script helpful for you. 🙂

I am assuming that you have tried ‘add_action( ‘woocommerce_order_status_pending_to_processing’, array( &$this, ‘custom_trigger_email_action’ ), 10, 2 );’ but it didn’t work.

If that is the case, then can can you please try adding
‘add_action( ‘woocommerce_order_status_processing’, array( &$this, ‘custom_trigger_email_action’ ), 10, 2 );’ and see if it works or not?

Please let me know the result.


Hi Priyanka,

Thanks for the reply, I already got it working by simply replacing ALL the ‘pending’ to ‘processing’. Seems there are multiple functions that hook into the actions, so all these names must be replaced. The script works perfect, thanks!

Priyanka Jagtap
Priyanka Jagtap

Hi Max,

You’re welcome 🙂

I am glad that you are able to achieve your requirement by replacing “pending” with “processing”.

Please let me know if you have any questions.

from purchased

Subscribe for more offers

To help you in these uncertain times, we are giving the Order Delivery Date plugin at 50% off.
Find out more