You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WooCommerce自定义邮件中获取子订单商品详情及图片

WooCommerce子订单邮件商品列表问题修复

问题1:仅显示单个商品的修复

你当前的代码在遍历订单商品时,每次循环都会重新赋值整个$message_body,相当于每次都把之前的内容覆盖,最后自然只剩最后一个商品的数据。

正确的写法是把邮件的固定框架(HTML头部、标题、表格表头)放在循环外面,循环里只生成每个商品对应的表格行,最后把所有行拼接到表格里。

问题2:获取商品图片的方法

从订单商品项中拿到对应的WC_Product对象,就能调用WooCommerce内置方法获取商品图片:

  • 用get_image()可以直接获取带样式的图片HTML代码
  • 用get_image_url()可以获取图片URL,自行拼接<img>标签

修改后的完整代码

// Enable custom statuses for WooCommerce Orders
add_action('init', 'register_custom_order_statuses');
function register_custom_order_statuses() {
    register_post_status('wc-shipped', array(
        'label' => __( 'Shipped', 'woocommerce' ),
        'public' => true,
        'exclude_from_search' => false,
        'show_in_admin_all_list' => true,
        'show_in_admin_status_list' => true,
        'label_count' => _n_noop('Shipped <span class="count">(%s)</span>', 'Shipped <span class="count">(%s)</span>')
    ));
    register_post_status('wc-readytocollect', array(
        'label' => __( 'Ready to collect', 'woocommerce' ),
        'public' => true,
        'exclude_from_search' => false,
        'show_in_admin_all_list' => true,
        'show_in_admin_status_list' => true,
        'label_count' => _n_noop('Ready to collect <span class="count">(%s)</span>', 'Ready to collect <span class="count">(%s)</span>')
    ));
}

// Add a custom order status to list of WC Order statuses
add_filter('wc_order_statuses', 'add_custom_order_statuses');
function add_custom_order_statuses($order_statuses) {
    $new_order_statuses = array();

    // add new order status before processing
    foreach ($order_statuses as $key => $status) {
        $new_order_statuses[$key] = $status;
        if ('wc-processing' === $key) {
            $new_order_statuses['wc-shipped']        = __('Shipped', 'woocommerce' );
            $new_order_statuses['wc-readytocollect'] = __('Ready to collect', 'woocommerce' );
        }
    }
    return $new_order_statuses;
}

// Send custom email notifications to sub orders only
add_action( 'woocommerce_order_status_changed', 'custom_order_statuses_email_notifications', 10, 4 );
function custom_order_statuses_email_notifications ($order_id, $from_status, $to_status, $order) {
    // Targeting sub-orders only
    if ( ! $order->get_parent_id() ) return;

    $status_label = '';
    $status_label_soobshenie = '';
    
    if ( $to_status === 'shipped' ) {
        $status_label  = __( 'Shipped', 'woocommerce' );
        $status_label_soobshenie  = __( 'Your order has been shipped', 'woocommerce' );
    } 
    elseif ( $to_status === 'readytocollect' ) {
        $status_label  = __( 'Ready to collect', 'woocommerce' );
        $status_label_soobshenie  = __( 'Your order is ready for collection', 'woocommerce' );
    }

    if ( !empty($status_label) ) {
        $mailer        = WC()->mailer(); // load the mailer class.
        $email_subject = sprintf( __( 'Order %s is %s' ), $order->get_order_number(), $status_label );

        // 初始化邮件主体的固定部分
        $message_body = '<html>
        <head></head>
        <body>
            <h1>'.$status_label.'</h1>
            <p>'.$status_label_soobshenie.'</p>
            <p></p>
            <table class="td" cellspacing="0" cellpadding="4"  style="width: 100%; color: #001a34; font-size: 14px; font-weight: normal;" border="0">
                    <thead>
                        <tr>
                            <th width="10%" class="td" style="text-align:left;" scope="col" >Image</th>
                            <th width="55%" class="td" style="text-align:left;" scope="col" >Product</th>
                            <th width="10%" class="td" style="text-align:right;" scope="col" >Qty</th>
                            <th width="25%" class="td" style="text-align:right;" scope="col" >Total</th>
                        </tr>
                    </thead>
                    <tbody>';

        // 遍历订单商品,生成每行数据
        foreach( $order->get_items() as $item_id => $item ){
            $product = $item->get_product(); // 获取商品对象
            $product_name  = $item->get_name(); // 商品名称
            $item_qty      = $item->get_quantity(); // 数量
            $line_total     = wc_price( $item->get_subtotal() ); // 格式化价格
            
            // 获取商品图片,这里用get_image()直接生成带样式的img标签,也可以用get_image_url()自定义
            $product_image = $product ? $product->get_image(array(80,80)) : '';

            // 拼接商品行
            $message_body .= '<tr>
                <td class="td" style="text-align:left;">'.$product_image.'</td>
                <td class="td" style="text-align:left;">'.$product_name.'</td>
                <td class="td" style="text-align:right;">'.$item_qty.'</td>
                <td class="td" style="text-align:right;">'.$line_total.'</td>
            </tr>';
        }

        // 闭合表格和HTML标签
        $message_body .= '</tbody></table></body></html>';

        $message = $mailer->wrap_message( $email_subject, $message_body );
        $mailer->send( $order->get_billing_email(), $email_subject, $message ); // Send email
    }
}

关键改动说明

  1. 拆分邮件结构:把HTML固定部分和商品循环部分分开,避免每次循环覆盖整个邮件内容,确保所有商品都能显示。
  2. 商品图片获取:通过$item->get_product()拿到商品对象,调用get_image()生成图片标签,同时处理了商品不存在的情况(加了判断)。
  3. 价格格式化:用wc_price()方法格式化商品总价,符合WooCommerce的货币显示规范。
  4. 优化状态文本:把状态提示文本改成更友好的用户提示,提升邮件可读性。

内容的提问来源于stack exchange,提问作者Lgane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 10:15:22