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

如何获取WooCommerce订单及客户邮件中选择字段的order_meta详情

WooCommerce 动态数量自定义结账字段显示解决方案

问题说明

已根据商品购买数量创建额外自定义结账字段,购买N件商品需填写N组对应字段,字段包含下拉选择项,需要在WooCommerce后台订单概览页、客户通知邮件中正常展示这些字段的meta数据。

原有代码问题梳理

  • 循环生成字段时,下拉选择类字段(性别、T恤尺码、夏令营经验)未加序号后缀,多件商品提交时后填写的数据会覆盖前序数据
  • 字段保存逻辑缺失下拉类字段的保存代码,且存在重复保存的冗余逻辑
  • 邮件字段调用逻辑硬写50组字段不合理,且调用的meta key与实际保存的key不匹配,部分下划线前缀的key不存在
  • 缺少后台订单页展示自定义字段的逻辑

修正后完整代码

// 根据购物车商品数量生成自定义结账字段
add_action( 'woocommerce_before_order_notes', 'person_details' );
function person_details($checkout) {
    global $woocommerce;
    $count = $woocommerce->cart->cart_contents_count;
    for($i=1; $i<= $count; $i++) {
        print ('第'.$i.'位参与人信息');
        // 姓名
        woocommerce_form_field( 'cstm_full_name'.$i, array(
            'type'          => 'text',
            'class'         => array('my-field-class form-row-wide'),
            'label'         => __('全名'),
            'required'      => true,
        ), $checkout->get_value( 'cstm_full_name'.$i ));
        echo '<div class="clear"></div>';
        // 性别
        woocommerce_form_field( 'cstm_gender'.$i, array(
            'type'          => 'select',
            'required'      => true,
            'class'         => array( 'my-field-class form-row-wide' ),
            'label'         => __( '性别' ),
            'options'       => array(
                 'blank'             => __( '请选择', 'njengah' ),
                 'jongen'           => __( '男', 'njengah' ),
                 'meisje'           => __( '女', 'njengah' ),
                 'genderneutraal'   => __( '其他', 'njengah' )
             )),
            $checkout->get_value( 'cstm_gender'.$i ));
        // 年龄
        woocommerce_form_field( 'cstm_leeftijd'.$i, array(
            'type'          => 'text',
            'class'         => array('my-field-class form-row-first'),
            'label'         => __('开营时年龄'),
            'required'      => true,
        ), $checkout->get_value( 'cstm_leeftijd'.$i ));
        // 当前所在组别
        woocommerce_form_field( 'cstm_groep'.$i, array(
            'type'          => 'text',
            'class'         => array('my-field-class form-row-last'),
            'label'         => __('当前所属组别'),
            'required'      => true,
        ), $checkout->get_value( 'cstm_groep'.$i ));
        // T恤尺码
        woocommerce_form_field( 'cstm_shirt'.$i, array(
            'type'          => 'select',
            'required'      => true,
            'class'         => array( 'my-field-class form-row-first' ),
            'label'         => __( 'T恤尺码' ),
            'options'       => array(
                 'blank'             => __( '请选择', 'njengah' ),
                 'Maat S'           => __( 'S', 'njengah' ),
                 'Maat M'           => __( 'M', 'njengah' ),
                 'Maat L'           => __( 'L', 'njengah' )
             )),
            $checkout->get_value( 'cstm_shirt'.$i ));
        // 夏令营参与经验
        woocommerce_form_field( 'cstm_ervaring'.$i, array(
            'type'          => 'select',
            'required'      => true,
            'class'         => array( 'my-field-class form-row-last' ),
            'label'         => __( '夏令营参与经验' ),
            'options'       => array(
                'blank'                     => __( '请选择', 'njengah' ),
                '1e keer Summer Camp'       => __( '第一次参与', 'njengah' ),
                '2e keer Summer Camp'       => __( '第二次参与', 'njengah' ),
                '3e keer Summer Camp'       => __( '第三次参与', 'njengah' ),
                '4e keer Summer Camp'       => __( '第四次及以上参与', 'njengah' )
             )),
            $checkout->get_value( 'cstm_ervaring'.$i ));
        echo '<div class="clearbox"></div>';
    }
}

// 保存自定义字段值到订单meta
add_action('woocommerce_checkout_update_order_meta', 'customise_checkout_field_update_order_meta');
function customise_checkout_field_update_order_meta($order_id) {
    global $woocommerce;
    $count = $woocommerce->cart->cart_contents_count;
    for($i=1; $i<= $count; $i++) {
        // 保存姓名
        if (!empty($_POST['cstm_full_name'.$i])) {
            update_post_meta($order_id, '第'.$i.'位参与人姓名', sanitize_text_field($_POST['cstm_full_name'.$i]));
        }
        // 保存性别
        if (!empty($_POST['cstm_gender'.$i])) {
            update_post_meta($order_id, '第'.$i.'位参与人性别', sanitize_text_field($_POST['cstm_gender'.$i]));
        }
        // 保存年龄
        if (!empty($_POST['cstm_leeftijd'.$i])) {
            update_post_meta($order_id, '第'.$i.'位参与人开营年龄', sanitize_text_field($_POST['cstm_leeftijd'.$i]));
        }
        // 保存组别
        if (!empty($_POST['cstm_groep'.$i])) {
            update_post_meta($order_id, '第'.$i.'位参与人当前组别', sanitize_text_field($_POST['cstm_groep'.$i]));
        }
        // 保存T恤尺码
        if (!empty($_POST['cstm_shirt'.$i])) {
            update_post_meta($order_id, '第'.$i.'位参与人T恤尺码', sanitize_text_field($_POST['cstm_shirt'.$i]));
        }
        // 保存参与经验
        if (!empty($_POST['cstm_ervaring'.$i])) {
            update_post_meta($order_id, '第'.$i.'位参与人夏令营参与经验', sanitize_text_field($_POST['cstm_ervaring'.$i]));
        }
    }
}

// 自定义字段添加到订单邮件
add_filter('woocommerce_email_order_meta_keys', 'my_custom_checkout_field_order_meta_keys', 10, 1);
function my_custom_checkout_field_order_meta_keys( $keys ) {
    // 获取订单商品数量动态生成字段
    $order = wc_get_order( get_the_ID() );
    if(!$order) return $keys;
    $count = $order->get_item_count();
    for($i=1; $i<= $count; $i++) {
        $keys[] = '第'.$i.'位参与人姓名';
        $keys[] = '第'.$i.'位参与人性别';
        $keys[] = '第'.$i.'位参与人开营年龄';
        $keys[] = '第'.$i.'位参与人当前组别';
        $keys[] = '第'.$i.'位参与人T恤尺码';
        $keys[] = '第'.$i.'位参与人夏令营参与经验';
    }   
    return $keys;
}

// 自定义字段显示到后台订单详情页
add_action( 'woocommerce_admin_order_data_after_billing_address', 'show_custom_fields_in_admin_order', 10, 1 );
function show_custom_fields_in_admin_order( $order ){
    $count = $order->get_item_count();
    for($i=1; $i<= $count; $i++) {
        echo '<p><strong>第'.$i.'位参与人信息:</strong></p>';
        echo '<p>姓名:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人姓名', true ) . '</p>';
        echo '<p>性别:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人性别', true ) . '</p>';
        echo '<p>开营年龄:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人开营年龄', true ) . '</p>';
        echo '<p>当前组别:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人当前组别', true ) . '</p>';
        echo '<p>T恤尺码:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人T恤尺码', true ) . '</p>';
        echo '<p>参与经验:' . get_post_meta( $order->get_id(), '第'.$i.'位参与人夏令营参与经验', true ) . '</p>';
    }
}

生效说明

将上述代码添加到主题的functions.php文件或者自定义代码片段插件中即可生效,所有字段会自动适配购物车商品数量,提交后的数据会同步展示在后台订单页和客户通知邮件中。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:45:11