WooCommerce Blocks结算页自定义字段无法传递至后端的问题
WooCommerce Blocks 自定义结算字段传值后端解决方案
核心问题原因
WooCommerce Blocks(基于Gutenberg)的结账流程依赖WooCommerce REST API,传统woocommerce_checkout_fields钩子仅对经典短码结账页生效。直接添加前端DOM字段但未在REST API schema中注册、未按规范设置字段命名,会导致字段值无法被后端识别并关联到订单。
分步解决方法
1. 注册自定义字段到REST API订单 Schema
让API能识别并接收这三个字段,添加以下PHP代码到插件或主题functions.php:
add_filter( 'woocommerce_rest_order_schema', 'register_custom_billing_fields_rest_schema' ); function register_custom_billing_fields_rest_schema( $schema ) { // 注册Bairro字段 $schema['properties']['billing']['properties']['bairro'] = array( 'description' => __( 'Bairro', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ); // 注册Número字段 $schema['properties']['billing']['properties']['numero'] = array( 'description' => __( 'Número', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ); // 注册CPF字段 $schema['properties']['billing']['properties']['cpf'] = array( 'description' => __( 'CPF', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ); return $schema; }
2. 前端按规范添加字段(兼容Blocks机制)
不要手动创建DOM元素,用WooCommerce Blocks官方提供的registerCheckoutField方法注册字段,确保字段命名与REST Schema对应:
// 确保在WooCommerce Blocks加载完成后执行 document.addEventListener('DOMContentLoaded', function() { if (window.wc?.blocksCheckout?.registerCheckoutField) { // 注册Bairro字段 window.wc.blocksCheckout.registerCheckoutField({ name: 'billing[bairro]', label: 'Bairro', type: 'text', location: 'billing', required: true, placeholder: 'Digite seu bairro', }); // 注册Número字段 window.wc.blocksCheckout.registerCheckoutField({ name: 'billing[numero]', label: 'Número', type: 'text', location: 'billing', required: true, placeholder: 'Digite o número da residência', }); // 注册CPF字段 window.wc.blocksCheckout.registerCheckoutField({ name: 'billing[cpf]', label: 'CPF', type: 'text', location: 'billing', required: true, placeholder: 'Digite seu CPF', }); } });
3. 后端保存字段值到订单元数据
添加PHP钩子,将API接收的字段值保存到订单元数据中:
add_action( 'woocommerce_checkout_create_order', 'save_custom_billing_fields_to_order', 10, 2 ); function save_custom_billing_fields_to_order( $order, $data ) { // 保存Bairro if ( isset( $data['billing']['bairro'] ) ) { $order->update_meta_data( '_billing_bairro', sanitize_text_field( $data['billing']['bairro'] ) ); $order->set_billing_bairro( sanitize_text_field( $data['billing']['bairro'] ) ); } // 保存Número if ( isset( $data['billing']['numero'] ) ) { $order->update_meta_data( '_billing_numero', sanitize_text_field( $data['billing']['numero'] ) ); $order->set_billing_numero( sanitize_text_field( $data['billing']['numero'] ) ); } // 保存CPF if ( isset( $data['billing']['cpf'] ) ) { $order->update_meta_data( '_billing_cpf', sanitize_text_field( $data['billing']['cpf'] ) ); $order->set_billing_cpf( sanitize_text_field( $data['billing']['cpf'] ) ); } }
4. 验证字段获取
完成以上步骤后,可通过以下方式在后端获取字段值:
// 假设$order是已获取的订单对象 $bairro = $order->get_meta( '_billing_bairro' ); $numero = $order->get_meta( '_billing_numero' ); $cpf = $order->get_meta( '_billing_cpf' ); // 或直接通过订单属性获取 $bairro = $order->get_billing_bairro();
内容的提问来源于stack exchange,提问作者xCUELHO
相关产品推荐
相关产品推荐

