By default, WooCommerce provides email notifications for standard order statuses like “processing,” “completed,” and “cancelled.” Suppose if you’ve implemented custom order statuses for your store, such as “Shipped” or any other status specific to your business process, you’ll likely want to send customized email notifications to your customers when their orders reach these statuses.
Solution: Send Customized Email for Custom Order Status
Let’s assume that you have a custom order status such as ‘Shipped’ . The code snippet will send more personalized and informative shipping messages by modifying the subject, heading and the Email content to your customers when the status gets changed to the custom order status ‘shipped’.
// Customize email content for this custom status email notification add_action('woocommerce_email_before_order_table', 'ts_custom_content_for_customer_shipping_email', 10, 4); function ts_custom_content_for_customer_shipping_email($order, $sent_to_admin, $plain_text, $email) { // Check if it's the "Customer Processing Order" email triggered by 'shipped' status if ($email->id === 'customer_processing_order' && $order->has_status('shipped')) { echo '<h4>Your order has been shipped!</h4>'; echo '<p>Your order has been successfully shipped. You can expect to receive it within the estimated delivery time.</p> <p>Thank you for choosing our store. If you have any questions or concerns, feel free to contact us.</p>'; } } // Add a custom order status to list of WC Order statuses add_filter('wc_order_statuses', 'ts_add_custom_order_statuses'); function ts_add_custom_order_statuses($order_statuses) { $new_order_statuses = $order_statuses; // Add new order status before processing if (isset($new_order_statuses['wc-processing'])) { $new_order_statuses['wc-shipped'] = __('Shipped', 'woocommerce'); } return $new_order_statuses; } // Adding custom status statuses to admin order list bulk dropdown add_filter('bulk_actions-edit-shop_order', 'ts_custom_dropdown_bulk_actions_shop_order', 50, 1); function ts_custom_dropdown_bulk_actions_shop_order($actions) { // Add new order status before processing if (isset($actions['mark_processing'])) { $actions['mark_shipped'] = __('Change status to shipped', 'woocommerce'); } return $actions; } // Add a custom order statuses action button (for orders with "processing" status) add_filter('woocommerce_admin_order_actions', 'ts_add_custom_order_status_actions_button', 100, 2); function ts_add_custom_order_status_actions_button($actions, $order) { $allowed_statuses = array('on-hold', 'processing', 'pending', 'shipped'); // Define allowed statuses // Display the button for all orders that have allowed status (as defined in the array) if (in_array($order->get_status(), $allowed_statuses)) { // The key slug defined from status with the name $action_slugs = array( 'shipped' => __('Shipped', 'woocommerce') ); // Loop through custom statuses foreach ($action_slugs as $action_slug => $name) { // Display custom status action buttons if ($order->get_status() !== $action_slug) { // Set the action button $actions[$action_slug] = array( 'url' => wp_nonce_url(admin_url('admin-ajax.php?action=woocommerce_mark_order_status&status=' . $action_slug . '&order_id=' . $order->get_id()), 'woocommerce-mark-order-status'), 'name' => $name, 'action' => $action_slug, ); } } } return $actions; } // Set styling for custom order status action button icon and List icon add_action('admin_head', 'ts_add_custom_order_status_actions_button_css'); function ts_add_custom_order_status_actions_button_css() { // The key slug defined from status with the icon code $action_slugs = array( 'shipped' => '\e019' ); ?> <style> <?php foreach ($action_slugs as $action_slug => $icon_code) : ?> .wc-action-button-<?php echo $action_slug; ?>::after { font-family: woocommerce !important; content: "<?php echo $icon_code; ?>" !important; } <?php endforeach; ?> </style> <?php } // Adding action for custom statuses add_filter('woocommerce_email_actions', 'ts_custom_email_actions', 20, 1); function ts_custom_email_actions($action) { $actions[] = 'woocommerce_order_status_wc-shipped'; return $actions; } add_action('woocommerce_order_status_wc-shipped', array('WC_Emails', 'send_transactional_email'), 10, 1); // Sending an email notification when order get a custom status add_action('woocommerce_order_status_shipped', 'ts_cutom_status_trigger_email_notification', 10, 2); function ts_cutom_status_trigger_email_notification($order_id, $order) { WC()->mailer()->get_emails()['WC_Email_Customer_Processing_Order']->trigger($order_id); } // Customize email heading for custom order status add_filter('woocommerce_email_heading_customer_processing_order', 'ts_custom_email_heading_for_custom_order_status', 10, 2); function ts_custom_email_heading_for_custom_order_status($heading, $order) { // Get the site name dynamically $site_name = get_bloginfo('name'); // Here your custom statuses slugs / Heading texts pairs $data = array( 'shipped' => sprintf(__('Your order from %s has been Shipped!', 'woocommerce'), $site_name) ); // Loop through each custom status / heading text pairs foreach ($data as $custom_status => $heading_text) { // Change an email notification heading text when an order gets a custom status if ($order->has_status($custom_status)) { $email = WC()->mailer()->get_emails()['WC_Email_Customer_Processing_Order']; // Get the specific WC_emails object $heading = $email->format_string($heading_text); // don't return directly } } return $heading; } // Customize email subject for custom order status add_filter('woocommerce_email_subject_customer_processing_order', 'ts_custom_email_subject_for_custom_order_status', 10, 2); function ts_custom_email_subject_for_custom_order_status($subject, $order) { // Get the site name dynamically $site_name = get_bloginfo('name'); // Here your custom statuses slugs / Subject texts pairs $data = array( 'shipped' => sprintf(__('Your order from %s has been Shipped!', 'woocommerce'), $site_name) ); // Loop through each custom status / subject text pairs foreach ($data as $custom_status => $subject_text) { // Change an email notification subject text when an order gets a custom status if ($order->has_status($custom_status)) { $email = WC()->mailer()->get_emails()['WC_Email_Customer_Processing_Order']; // Get the specific WC_emails object $subject = $email->format_string($subject_text); // don't return directly } } return $subject; } add_filter( 'gettext', 'ts_translate_woocommerce_strings_emails', 10, 3 ); function ts_translate_woocommerce_strings_emails( $translated, $untranslated, $domain ) { if ( 'woocommerce' === $domain ) { $translated = str_ireplace( 'Hi %s,', '', $untranslated ); // HIDE $translated = str_ireplace( 'Just to let you know — we\'ve received your order #%s, and it is now being processed:', '', $untranslated ); // EDIT } return $translated; }
Output
If you’ve defined a custom order status called ‘Shipped’ in your WooCommerce store and when an order’s status changes to ‘Shipped’, it triggers specific actions and email notifications. The email adds a personalized message informing customers that their order has been shipped and provides additional details regarding the shipping details.
In the same way, you can add you can also edit WooCommerce Processing Order email either to give customers a coupon or a link to redirect customers back to the shop page.