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

如何让WooCommerce新增账单字段数据纳入官方账单结构?

WooCommerce自定义账单字段纳入官方地址结构解决方案

我在WooCommerce的「我的账户」账单地址页面添加了两个仅对administrator角色可见的字段:

  • 标签为「我有附加费」的复选框(需在邮件中显示)
  • 标签为「NIF/CIF」的公司税号输入字段

目前这两个字段可在账户编辑页(my-account/edit-address/billing/)和结账页编辑,但数据仅在邮件的地址区域外显示,且无法在生成的发票中展示。以下是将其纳入WooCommerce官方账单地址结构的安全实现方案:


一、调整「我有附加费」复选框字段

将字段改为WooCommerce标准账单字段,让系统自动将其纳入地址渲染流程(含邮件、发票):

// 添加管理员可见的复选框到账单字段
add_filter( 'woocommerce_billing_fields', 'custom_checkbox_below_billing_company' );
function custom_checkbox_below_billing_company( $fields ) {
    if ( user_can( wp_get_current_user(), 'administrator' ) ) {
        $fields['billing_surcharge'] = array(
            'type'          => 'checkbox',
            'label'         => __( '我有附加费', 'woocommerce' ),
            'class'         => array('form-row-wide'),
            'priority'      => 30,
            'required'      => false,
            'clear'         => true,
            'default'       => 0,
            'show_in_email' => true,
            'show_in_address' => true,
        );
    }
    return $fields;
}

// 保存复选框值到用户meta
add_action( 'woocommerce_customer_save_address', 'save_billing_surcharge_checkbox', 10, 2 );
function save_billing_surcharge_checkbox( $customer_id, $load_address ) {
    $value = isset( $_POST['billing_surcharge'] ) ? sanitize_text_field( $_POST['billing_surcharge'] ) : '0';
    update_user_meta( $customer_id, 'billing_surcharge', $value );
}

// 同步字段值到订单meta(供发票/订单详情读取)
add_action( 'woocommerce_checkout_create_order', 'sync_billing_surcharge_to_order', 10, 2 );
function sync_billing_surcharge_to_order( $order, $data ) {
    if ( user_can( $order->get_user_id(), 'administrator' ) ) {
        $surcharge_value = get_user_meta( $order->get_user_id(), 'billing_surcharge', true );
        $order->update_meta_data( '_billing_surcharge', $surcharge_value );
    }
}

// 让字段显示在邮件的客户详情地址区域
add_filter( 'woocommerce_email_customer_details_fields', 'include_surcharge_in_email_address', 10, 3 );
function include_surcharge_in_email_address( $fields, $sent_to_admin, $order ) {
    if ( user_can( $order->get_user_id(), 'administrator' ) ) {
        $surcharge_value = $order->get_meta( '_billing_surcharge' ) ?: get_user_meta( $order->get_user_id(), 'billing_surcharge', true );
        $fields['billing_surcharge'] = array(
            'label' => __( '我有附加费', 'woocommerce' ),
            'value' => $surcharge_value ? '是' : '否',
        );
    }
    return $fields;
}

// 让字段显示在后台订单页的账单地址区域
add_filter( 'woocommerce_admin_billing_fields', 'include_surcharge_in_admin_address' );
function include_surcharge_in_admin_address( $fields ) {
    if ( user_can( get_current_user_id(), 'administrator' ) ) {
        $fields['billing_surcharge'] = array(
            'label' => __( '我有附加费', 'woocommerce' ),
            'show'  => true,
        );
    }
    return $fields;
}

修改说明:

  • 字段名改为billing_surcharge,遵循WooCommerce账单字段命名规范
  • 添加show_in_email/show_in_address标记,让系统识别为地址结构的一部分
  • 新增订单meta同步逻辑,确保发票、订单详情能读取到字段值
  • 保留管理员权限控制,避免普通用户访问

二、调整NIF/CIF税号字段

同样改为标准账单字段,替换原有自定义meta逻辑:

// 添加管理员可见的NIF/CIF字段到账单字段
add_filter( 'woocommerce_billing_fields', 'add_custom_billing_nif_field' );
function add_custom_billing_nif_field( $fields ) {
    $user = wp_get_current_user();
    if ( ! empty( $user ) && in_array( 'administrator', (array) $user->roles ) ) {
        $fields['billing_nif'] = array(
            'label'       => __( 'NIF/CIF', 'woocommerce' ),
            'placeholder' => __( 'B12345678', 'woocommerce' ),
            'required'    => true,
            'clear'       => false,
            'type'        => 'text',
            'default'     => get_user_meta( $user->ID, 'billing_nif', true ),
            'class'       => array('form-row-wide'),
            'priority'    => 25,
            'show_in_email' => true,
            'show_in_address' => true,
        );
    }
    return $fields;
}

// 保存字段值到用户meta
add_action( 'woocommerce_customer_save_address', 'save_billing_nif_field', 10, 2 );
function save_billing_nif_field( $customer_id, $load_address ) {
    if ( isset( $_POST['billing_nif'] ) ) {
        update_user_meta( $customer_id, 'billing_nif', wc_clean( $_POST['billing_nif'] ) );
    }
}

// 同步字段值到订单meta
add_action( 'woocommerce_checkout_create_order', 'sync_billing_nif_to_order', 10, 2 );
function sync_billing_nif_to_order( $order, $data ) {
    $user_id = $order->get_user_id();
    if ( $user_id && user_can( $user_id, 'administrator' ) ) {
        $nif_value = get_user_meta( $user_id, 'billing_nif', true );
        if ( $nif_value ) {
            $order->update_meta_data( '_billing_nif', $nif_value );
        }
    }
}

// 在订单详情页、感谢页显示字段
add_action( 'woocommerce_order_details_after_order_table', 'show_billing_nif_in_order_details', 20 );
add_action( 'woocommerce_thankyou', 'show_billing_nif_in_order_details' );
function show_billing_nif_in_order_details( $order ) {
    if ( is_a( $order, 'WC_Order' ) ) {
        $nif_value = $order->get_meta( '_billing_nif' ) ?: get_user_meta( $order->get_user_id(), 'billing_nif', true );
    } else {
        $user_id = get_post_meta( $order, '_customer_user', true );
        $nif_value = get_post_meta( $order, '_billing_nif', true ) ?: get_user_meta( $user_id, 'billing_nif', true );
    }
    if ( $nif_value ) {
        echo '<p><strong>' . __( 'NIF/CIF:', 'woocommerce' ) . '</strong> ' . esc_html( $nif_value ) . '</p>';
    }
}

// 在后台订单页的账单地址区域显示字段
add_filter( 'woocommerce_admin_billing_fields', 'include_nif_in_admin_billing' );
function include_nif_in_admin_billing( $fields ) {
    if ( user_can( get_current_user_id(), 'administrator' ) ) {
        $fields['billing_nif'] = array(
            'label' => __( 'NIF/CIF', 'woocommerce' ),
            'show'  => true,
        );
    }
    return $fields;
}

修改说明:

  • 替换原有woocommerce_checkout_fields钩子为woocommerce_billing_fields,确保字段在账户地址编辑页和结账页都能显示
  • 字段名改为billing_nif,遵循官方命名规范
  • 移除自定义邮件显示逻辑,show_in_email标记会让系统自动将字段纳入邮件地址区域
  • 用wc_clean()、esc_html()确保输入输出安全,防止XSS攻击

关键注意事项

  1. 命名规范:自定义账单字段必须以billing_开头,WooCommerce才会将其识别为官方地址结构的一部分,自动支持邮件、发票(含官方PDF发票插件)渲染
  2. 数据同步:必须将用户meta同步到订单meta,因为发票、订单详情优先读取订单层面的元数据
  3. 权限控制:全程保留管理员角色判断,避免普通用户看到或修改这些字段
  4. 安全处理:所有用户输入必须经过清洗,输出必须经过转义,确保站点安全

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:49:55