How to Send a Custom Email in WooCommerce: A Beginner’s Guide
WooCommerce is a fantastic e-commerce platform, but sometimes the standard email notifications just don’t cut it. Maybe you want to add a personal touch, include extra information, or completely overhaul the design. Learning how to send a custom email in WooCommerce unlocks a whole new level of control over your customer communication.
This guide will walk you through the process, even if you’re a complete beginner. We’ll cover the basics, explain the code, and give you real-life examples to get you started.
Why Send Custom Emails?
The default WooCommerce emails are functional, but they lack personality and might not address specific needs of your business. Here’s why you might want to create custom emails:
- Brand consistency: Your emails are an extension of your brand. Customizing them allows you to use your brand colors, logo, and voice, creating a more cohesive customer experience. Imagine your brand is quirky and fun – a standard, plain email might feel out of character.
- Enhanced communication: Include specific product instructions, warranty details, personalized messages, or any other information relevant to the customer’s purchase. For example, if you sell handmade ceramics, you might include care instructions in the order confirmation email.
- Targeted marketing: Send customized promotions or upselling opportunities based on past purchases. If a customer buys a camera lens, you can send an email with a discount on compatible accessories.
- Improved customer service: Respond Explore this article on How To Add Discount Ad On Woocommerce Shop to specific inquiries or issues with tailored emails that address their concerns. This shows customers you value their business and are paying attention to their needs.
Understanding the WooCommerce Email System
Before diving into the code, let’s understand how WooCommerce handles emails. WooCommerce uses a class called `WC_Email` as the base for all its email notifications. This class handles the email template, headers, subject, and content. When an event occurs (like a new order), WooCommerce triggers the appropriate email based on the store settings.
You have two main ways to customize emails:
1. Override Existing Templates: This method involves copying the default WooCommerce email templates into your theme and modifying them. It’s a quick way to make minor changes to the layout and content.
2. Create Custom Email Classes: This approach allows you to build completely new email notifications from scratch, offering the most flexibility. This is ideal for more significant changes or sending emails for custom events.
We’ll focus on the second, more robust, method of creating custom email classes.
Step-by-Step: Creating a Custom Email
Here’s a detailed guide to creating and sending a custom WooCommerce email:
1. Create a Plugin (Recommended)
It’s best practice to keep custom code in a plugin to prevent it from being overwritten when you update your theme. Create a new folder in your `wp-content/plugins/` directory, for example, `custom-woocommerce-emails`. Inside this folder, create a PHP file, for example, `custom-woocommerce-emails.php`.
Add the following code to the `custom-woocommerce-emails.php` file:
<?php /**
// Prevent direct access
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
// Include our email class
require_once plugin_dir_path( __FILE__ ) . ‘includes/class-wc-custom-email.php’;
// Add custom emails to WooCommerce
function add_custom_emails( $email_classes ) {
$email_classes[‘WC_Custom_Email’] = new WC_Custom_Email();
return $email_classes;
}
add_filter( ‘woocommerce_email_classes’, ‘add_custom_emails’ );
2. Create the Email Class
Create a new folder inside your plugin directory named `includes`. Inside the `includes` folder, create a file named `class-wc-custom-email.php`.
Add the following code to the `class-wc-custom-email.php` file. This is where the magic happens!
<?php
if ( ! defined( ‘ABSPATH’ ) ) {
exit; // Exit if accessed directly
}
if ( ! class_exists( ‘WC_Email’ ) ) {
return; // Exit if WooCommerce is not active
}
class WC_Custom_Email extends WC_Email {
public function __construct() {
$this->id = ‘wc_custom_email’;
$this->title = __( ‘Custom Email’, ‘woocommerce’ );
$this->description = __( ‘A custom email sent when something specific happens.’, ‘woocommerce’ );
$this->template_html = ’emails/custom-email.php’; // Template file path
$this->template_plain = ’emails/plain/custom-email.php’;
$this->template_base = plugin_dir_path( __FILE__ ) . ‘templates/’; // Where template are stored (in plugin folder)
$this->subject = __( ‘A custom email!’, ‘woocommerce’ );
$this->heading = __( ‘Custom Email’, ‘woocommerce’ );
$this->customer_email = true; // Email sent to customer
// Trigger this email when a specific action occurs (replace ‘your_custom_action’ with your actual action)
add_action( ‘your_custom_action’, array( $this, ‘trigger’ ) );
// Call parent constructor to load any defaults and initialise settings
parent::__construct();
// Define user settings (which you will be able to edit in WooCommerce settings)
$this->form_fields = array(
‘enabled’ => array(
‘title’ => __( ‘Enable/Disable’, ‘woocommerce’ ),
‘type’ => ‘checkbox’,
‘label’ => __( ‘Enable this email notification’, ‘woocommerce’ ),
‘default’ => ‘yes’,
),
‘subject’ => array(
‘title’ => __( ‘Subject’, ‘woocommerce’ ),
‘type’ => ‘text’,
‘description’ => sprintf( __( ‘This controls the email subject line. Leave blank to use the default subject: %s
.’, ‘woocommerce’ ), $this->subject ),
‘placeholder’ => ”,
‘default’ => ”,
),
‘heading’ => array(
‘title’ => __( ‘Email Heading’, ‘woocommerce’ ),
‘type’ => ‘text’,
‘description’ => sprintf( __( ‘This controls the main heading contained within the email notification. Leave blank to use the default heading: %s
.’, ‘woocommerce’ ), $this->heading ),
‘placeholder’ => ”,
‘default’ => ”,
),
‘additional_content’ => array(
‘title’ => __( ‘Additional content’, ‘woocommerce’ ),
‘description’ => __( ‘Text to appear below the main email content.’, ‘woocommerce’ ),
‘type’ => ‘textarea’,
‘default’ => ”,
‘placeholder’ => __( ‘Additional content’, ‘woocommerce’ ),
),
);
}
/
* Trigger Function
*
* This function is called when the custom action is triggered.
*
* @param mixed $data Can be anything
*/
public function trigger( $data ) {
// Check if the email is enabled
if ( ! $this->is_enabled() || ! $this->get_recipient() ) {
return;
}
$this->placeholders[‘{data}’] = $data; // Pass the data to the email template
// Send the email
$this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
}
/
* Get email subject.
*
* @since 3.1.0
* @return string
*/
public function get_default_subject() {
return $this->subject;
}
/
* Get email heading.
*
* @since 3.1.0
* @return string
*/
public function get_default_heading() {
return $this->heading;
}
/
* get_content_html function.
*
* @access public
* @return string
*/
public function get_content_html() {
ob_start();
wc_get_template( $this->template_html, array(
’email_heading’ => $this->get_heading(),
‘additional_content’ => $this->get_additional_content(),
‘data’ => $this->placeholders[‘{data}’], // Accessing the data here
‘sent_to_admin’ => false,
‘plain_text’ => false,
’email’ => $this,
), ”, $this->template_base );
return ob_get_clean();
}
/
* get_content_plain function.
*
* @access public
* @return string
*/
public function get_content_plain() {
ob_start();
wc_get_template( $this->template_plain, array(
’email_heading’ => $this->get_heading(),
‘additional_content’ => $this->get_additional_content(),
‘data’ => $this->placeholders[‘{data}’], // Accessing the data here
‘sent_to_admin’ => false,
‘plain_text’ => true,
’email’ => $this,
), ”, $this->template_base );
return ob_get_clean();
}
/
* Get additional content.
*
* @return string
*/
public function get_additional_content() {
if ( isset( $this->settings[‘additional_content’] ) ) {
return $this->format_string( $this->settings[‘additional_content’] );
} else {
return ”;
}
}
/
* Initialise Check out this post: How To Check Woocommerce Shipping Costs Without An Order Settings Form Fields
*
* Add settings to the WooCommerce setting screen.
*
* @access public
* @return void
*/
public function init_form_fields() {
$this->form_fields = apply_filters( ‘wc_custom_email_form_fields’, $this->form_fields );
}
}
Explanation of the Code:
- `WC_Custom_Email` extends `WC_Email` to inherit its functionality.
- `__construct()`: This is the constructor of the class. It defines the email ID, title, description, template paths, subject, heading, recipient, and most importantly, the action that triggers the email. We’re using `your_custom_action` which you’ll replace.
- `trigger($data)`: This function is called when the `your_custom_action` hook is triggered. It checks if the email is enabled and then sends the email using the template.
- `get_content_html()` and `get_content_plain()`: These functions load the HTML and plain text email templates respectively.
- `init_form_fields()`: This function defines the settings that will appear on the WooCommerce settings page for this email. You can control the subject, heading, and enable/disable the email.
- `get_additional_content()`: Retrieve value for additonal content in text-field of email-form.
3. Create Email Templates
Create another folder inside the `includes` directory named `templates`. Inside `templates`, create a folder named `emails`. Inside that, create two files: `custom-email.php` (for the HTML version) and `plain/custom-email.php` (for the plain text version).
`custom-email.php` (HTML Template):
<?php /**
defined( ‘ABSPATH’ ) || exit;
/*
* @hooked WooCommerceEmailsTemplates::email_header() Output the email header
*/
do_action( ‘woocommerce_email_header’, $email_heading, $email ); ?>
<?php
/*
* @hooked WooCommerceEmailsTemplates::email_footer() Output the email footer
*/
do_action( ‘woocommerce_email_footer’, $email );
`plain/custom-email.php` (Plain Text Template):
<?php /**
defined( ‘ABSPATH’ ) || exit;
echo “= ” . esc_html( $email_heading ) . ” =nn”;
/* translators: %s: Customer first name */
echo esc_html__( ‘Hi there,’, ‘woocommerce’ ) . “nn”;
echo esc_html( $additional_content ) . “nn”;
echo esc_html( sprintf( ‘Here is the data passed: %s’, $data ) ) . “nn”;
echo “n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=nn”;
echo apply_filters( ‘woocommerce_email_footer_text’, get_bloginfo( ‘name’ ) );
Explanation of the Templates:
- These templates define the structure and content of your email.
- “: This is where you display the data you passed to the `trigger()` function.
- `$email_heading` and `$additional_content`: These variables are passed from the email class and contain the heading and additional content defined in the WooCommerce settings.
- `do_action( ‘woocommerce_email_header’, $email_heading, $email );` and `do_action( ‘woocommerce_email_footer’, $email );`: These hooks include the standard WooCommerce email header and footer.
4. Activate the Plugin
Go to your WordPress admin panel, navigate to “Plugins,” and activate the “Custom WooCommerce Emails” plugin.
5. Configure the Email in WooCommerce
Go to WooCommerce -> Settings -> Emails. You should see “Custom Email” listed there. Click on it to configure the email settings, such as enabling/disabling the email, changing the subject, and the heading. Also, you can modify text in “Additional content” field.
6. Trigger the Email
Now, you need to trigger the email. Remember the line:
add_action( 'your_custom_action', array( $this, 'trigger' ) );
This is the hook that triggers the email. You need to call this action somewhere in your code when you want the email to be sent. For example, let’s say you want to send an email when an order is placed. You could modify your plugin or theme’s `functions.php` file and add something like this:
function send_custom_email_on_order( $order_id ) { $order = wc_get_order( $order_id );
// You can pass any data you want to the email
$data = array(
‘order_id’ => $order_id,
‘customer_name’ => $order->get_billing_first_name() . ‘ ‘ . $order->get_billing_last_name(),
‘order_total’ => $order->get_formatted_order_total(),
);
do_action( ‘your_custom_action’, $data );
}
add_action( ‘woocommerce_thankyou’, ‘send_custom_email_on_order’, 10, 1 );
Explanation:
- `send_custom_email_on_order()`: This function is called when the `woocommerce_thankyou` action is triggered (i.e., when the order confirmation page is displayed).
- `wc_get_order( $order_id )`: This retrieves the order object.
- `$data`: This array contains the data you want to pass to the email template.
- `do_action( ‘your_custom_action’, $data )`: This is where you trigger your custom email. The `$data` array is passed to the `trigger()` function in your email class.
- `add_action( ‘woocommerce_thankyou’, ‘send_custom_email_on_order’, 10, 1 );`: This hooks the `send_custom_email_on_order()` function to the `woocommerce_thankyou` action.
Important: Replace `your_custom_action` in *both* your email class and the hook to trigger the email with a unique, descriptive name (e.g., `wc_custom_order_notification`). *Do not use generic names!*
7. Test Your Email
Place a test order on your WooCommerce store. You should receive your custom email notification. The email will show any additional content and the array of data that you have defined in the `send_custom_email_on_order` function.
Debugging Tip:
If your email isn’t sending, check the following:
- Is the email enabled in WooCommerce settings? Make sure the “Enable this email notification” checkbox is checked.
- Is the action being triggered? Use `error_log()` or `var_dump()` to check if your function that triggers the email is being called.
- Are there any PHP errors? Enable WordPress debugging by adding `define( ‘WP_DEBUG’, true );` to your `wp-config.php` file.
- Check your spam folder. Sometimes emails end up there.
Real-Life Example: Sending a Custom Order Confirmation Email with Estimated Delivery
Let’s say you want to send a custom order confirmation email that includes an estimated delivery date based on the shipping method.
First, let’s modify our `send_custom_email_on_order` function.
function send_custom_email_on_order( $order_id ) { $order = wc_get_order( $order_id );
// Calculate the estimated delivery date (example: adding 3 business days)
$delivery_date = date(‘Y-m-d’, strtotime( “+3 weekdays”, time()));
$data = array(
‘order_id’ => $order_id,
‘customer_name’ => $order->get_billing_first_name() . ‘ ‘ . $order->get_billing_last_name(),
‘order_total’ => $order->get_formatted_order_total(),
‘estimated_delivery’ => $delivery_date,
);
do_action( ‘your_custom_action’, $data );
}
add_action( ‘woocommerce_thankyou’, ‘send_custom_email_on_order’, 10, 1 );
Now, modify your `custom-email.php` template to display the estimated delivery date:
<?php /**
defined( ‘ABSPATH’ ) || exit;
do_action( ‘woocommerce_email_header’, $email_heading, $email ); ?>
<?php
do_action( ‘woocommerce_email_footer’, $email );
Now, when an order is placed, the customer will receive an email including their name, order total, and the estimated delivery date. The additional content can be customized in your WooCommerce dashboard too!
Conclusion
Sending custom emails in WooCommerce is a powerful way to improve communication with your customers and build a stronger brand. By creating custom email classes, you gain complete control over the content and design of your email notifications. While it requires some coding, the flexibility and benefits make it well worth the effort. Remember to always test thoroughly and use best practices to ensure your emails are delivered correctly. Now go forth and craft some amazing emails!