Extending WooCommerce functionalities is essential for many online stores. This tutorial explains how to create a custom order status and send tailored emails whenever this status is triggered. This is ideal for stores with unique workflows.
Step 1: Register a Custom Order Status in WooCommerce
Use the register_post_status function to define a new order status. Add the following code to your child theme’s functions.php or within a custom plugin:
// Define custom status
function add_custom_order_status() {
register_post_status( 'wc-custom-status', array(
'label' => _x( 'Custom Status', 'Order status', 'your-text-domain' ),
'public' => true,
'exclude_from_search' => false,
'show_in_admin_all_list' => true,
'show_in_admin_status_list' => true,
'label_count' => _n_noop( 'Custom Status (%s)', 'Custom Status (%s)', 'your-text-domain' )
) );
}
add_action( 'init', 'add_custom_order_status' );
Step 2: Make the Status Appear in Order Filters
To show this status in WooCommerce admin filters, use wc_order_statuses:
// Add to order status filter
function add_custom_order_status_to_filter( $order_statuses ) {
$order_statuses['wc-custom-status'] = _x( 'Custom Status', 'Order status', 'your-text-domain' );
return $order_statuses;
}
add_filter( 'wc_order_statuses', 'add_custom_order_status_to_filter' );
Step 3: Trigger Emails on Custom Status
Register an email action using the woocommerce_email_actions hook:
// Add custom email action
function add_custom_email_action( $email_actions ) {
$email_actions[] = 'woocommerce_order_status_wc-custom-status';
return $email_actions;
}
add_filter( 'woocommerce_email_actions', 'add_custom_email_action' );
Step 4: Create a Custom Email Handler
Define a class that extends WC_Email and controls the custom email logic. Save this as custom-new-order-email.php:
class Custom_New_Order_Email extends WC_Email {
public function __construct() {
$this->id = 'custom_new_order';
$this->title = __( 'Custom Order Notice', 'your-text-domain' );
$this->description = __( 'Sent when an order is marked with the custom status.', 'your-text-domain' );
$this->heading = __( 'New Custom Order', 'your-text-domain' );
$this->subject = __( 'Order #{order_number} - Custom Status', 'your-text-domain' );
$this->template_html = 'emails/custom-new-order.php';
$this->template_plain = 'emails/plain/custom-new-order.php';
$this->template_base = plugin_dir_path( __FILE__ );
$this->placeholders = array(
'{order_number}' => '',
);
parent::__construct();
}
public function trigger( $order_id ) {
$this->object = wc_get_order( $order_id );
$this->recipient = $this->object->get_billing_email();
$this->placeholders['{order_number}'] = $this->object->get_order_number();
$this->heading = apply_filters( 'woocommerce_email_heading_' . $this->id, $this->heading, $this->object );
$this->subject = apply_filters( 'woocommerce_email_subject_' . $this->id, $this->subject, $this->object );
parent::trigger( $order_id );
}
}
Step 5: Hook Your Custom Email into WooCommerce
Connect your custom email class using woocommerce_email_classes like so:
// Include the custom email class
function add_custom_email_class( $email_classes ) {
require_once 'path/to/custom-new-order-email.php'; // Adjust path
$email_classes['Custom_New_Order_Email'] = new Custom_New_Order_Email();
return $email_classes;
}
add_filter( 'woocommerce_email_classes', 'add_custom_email_class' );
Wrapping Up
With these steps, you’ve successfully integrated a custom order status and linked it to an automated email in WooCommerce. This helps maintain a smoother workflow and improves customer communication.
Tip: Always develop in a staging environment and use a child theme or custom plugin to keep your setup upgrade-safe.
Need reference? Visit the official WooCommerce email customization docs.
