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.