如何在WooCommerce管理员新订单邮件通知中添加客户状态及累计订单数
Got it, let's fix this problem for you! The core issue with your original has_bought() function is that it relies on get_current_user_id()—but when the admin receives the new order email, the "current user" is the admin themselves, not the customer who placed the order. That's why it's failing.
We'll rebuild the logic to use the order's billing email (works for both logged-in and guest customers) and add the info directly to the admin new order email without modifying template files (safer for theme/plugin updates).
Step 1: Create a Function to Get Customer Order Details
This function will take an order object, check how many orders the customer (identified by email) has placed before, and return their type (new/returning) and order count.
function get_customer_order_info( $order ) { // Grab the billing email from the order $billing_email = $order->get_billing_email(); $previous_order_count = 0; // Check if this is a registered user $user = get_user_by( 'email', $billing_email ); if ( $user ) { // Use WooCommerce's built-in function to get total orders for the user $total_orders = wc_get_customer_order_count( $user->ID ); } else { // For guest customers, count orders by matching billing email $guest_orders = get_posts( array( 'post_type' => 'shop_order', 'post_status' => array( 'wc-completed', 'wc-processing', 'wc-on-hold' ), // Adjust statuses as needed 'meta_query' => array( array( 'key' => '_billing_email', 'value' => $billing_email, 'compare' => '=', ), ), 'fields' => 'ids', 'posts_per_page' => -1, ) ); $total_orders = count( $guest_orders ); } // Subtract 1 to exclude the current order (since it's just been placed) $current_order_status = $order->get_status(); $included_statuses = array( 'completed', 'processing', 'on-hold' ); // Match statuses above if ( in_array( $current_order_status, $included_statuses ) ) { $previous_order_count = max( 0, $total_orders - 1 ); } else { $previous_order_count = $total_orders; } // Determine customer type $customer_type = $previous_order_count > 0 ? '回头客' : '新客户'; return array( 'type' => $customer_type, 'count' => $previous_order_count, ); }
Step 2: Add the Info to Admin New Order Email
We'll use a WooCommerce email hook to inject the customer info right after the order table in the admin's new order email. No template edits required!
add_action( 'woocommerce_email_after_order_table', 'add_customer_info_to_admin_order_email', 20, 4 ); function add_customer_info_to_admin_order_email( $order, $sent_to_admin, $plain_text, $email ) { // Only show this on the admin's new order email if ( $sent_to_admin && $email->id === 'new_order' ) { $customer_info = get_customer_order_info( $order ); // Output the formatted info echo '<p><strong>客户类型:' . esc_html( $customer_info['type'] ) . '</strong> 累计订单数:' . esc_html( $customer_info['count'] ) . '</p>'; } }
How It Works & Key Notes
- Covers All Customers: Uses billing email to identify both logged-in users (via their user account) and guests (via order metadata).
- Accurate Order Count: Subtracts the current order from the total to show how many orders the customer placed before this one.
- Safe Updates: Uses hooks instead of modifying template files, so your changes won't be lost when updating WooCommerce or your theme.
- Customizable Statuses: Adjust the
post_statusarray in the function if you want to count only completed orders, or include other statuses like pending.
Feasibility
This solution is fully feasible and meets all your requirements:
- It clearly labels new vs returning customers for warehouse staff.
- Works for both logged-in and guest customers.
- Displays the exact cumulative order count (excluding the current order).
Just add these code snippets to your theme's functions.php file, or use a custom plugin to keep them safe from theme updates.
内容的提问来源于stack exchange,提问作者Kees

