WordPress/WooCommerce中COD支付订单On Hold状态邮件未触发求助
Fix: COD Orders Not Triggering On-Hold Email in WooCommerce 3.3.5
Hey there, let's sort out why your COD orders aren't sending the "Order On Hold" email even though the status is updating correctly. Here's the breakdown and fix:
The Root Issue
Your current code sets the order status to on-hold directly, but WooCommerce's email system relies on status transition hooks (like woocommerce_order_status_pending_to_on-hold_notification) to trigger emails. Two gaps are causing the problem:
- The
woocommerce_thankyouaction might run after default status processing, so the transition hook doesn't fire as expected. - Your existing email hook function only handles
pending_to_processingtransitions, not thepending_to_on-holdshift that COD orders use.
Revised Code to Fix the Email Trigger
Here's updated code that preserves your status logic while ensuring the On-Hold email fires for COD, BACS, and Cheque orders:
add_action( 'woocommerce_thankyou', 'wc_auto_complete_paid_order', 20, 1 ); function wc_auto_complete_paid_order( $order_id ) { if ( ! $order_id ) return; $order = wc_get_order( $order_id ); $current_status = $order->get_status(); // Handle BACS, COD, Cheque: Set to On Hold and ensure email triggers if ( in_array( $order->get_payment_method(), array( 'bacs', 'cod', 'cheque' ) ) ) { // Avoid redundant status updates if ( $current_status !== 'on-hold' ) { // Update status with transition hooks enabled (default behavior) $order->update_status( 'on-hold', 'Awaiting payment confirmation' ); // Fallback: Manually trigger the On-Hold email if hook didn't fire if ( class_exists( 'WC_Email_Customer_On_Hold_Order' ) ) { $email = new WC_Email_Customer_On_Hold_Order(); $email->trigger( $order_id ); } } } // Handle PayPal & other paid methods: Set to Completed else { if ( $current_status !== 'completed' ) { $order->update_status( 'completed', 'Payment automatically confirmed' ); } } } function adjust_woocommerce_email_triggers( $email_class ) { // Keep your existing logic: Replace Processing email with On-Hold for pending->processing remove_action( 'woocommerce_order_status_pending_to_processing_notification', array( $email_class->emails['WC_Email_Customer_Processing_Order'], 'trigger' ) ); add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $email_class->emails['WC_Email_Customer_On_Hold_Order'], 'trigger' ) ); // Critical addition: Map pending->on-hold transition to On-Hold email add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $email_class->emails['WC_Email_Customer_On_Hold_Order'], 'trigger' ) ); } add_action( 'woocommerce_email', 'adjust_woocommerce_email_triggers' );
Key Improvements:
- Manual Email Fallback: If the status transition hook fails to fire (common on the thank-you page), we manually instantiate and trigger the On-Hold email.
- Status Checks: Prevents redundant status updates that could cause loops or duplicate actions.
- Explicit Email Mapping: Adds the
pending_to_on-holdhook to ensure COD/BACS orders trigger the correct email when their status changes. - Admin Notes: Optional status notes help track why an order was updated, making debugging easier.
Testing Steps:
- Place a test order using COD payment.
- Confirm the order status is set to "On Hold" in WooCommerce Admin.
- Check the customer's inbox (and spam folder) for the On-Hold email.
- If issues persist, check
WooCommerce > Status > Logsfor email-related errors.
内容的提问来源于stack exchange,提问作者Fjott
相关产品推荐
相关产品推荐

