如何将WooCommerce自定义产品元字段值保存至订单项元数据
解决方案
1. 现有代码验证
你的产品自定义元字段创建与保存代码基本正确,但存在两处可优化/补全的点:
desc_tip参数应使用布尔值true而非字符串'true',修正后更符合WooCommerce规范- 原代码未兼容可变产品的子变体保存操作,
woocommerce_process_product_meta钩子不会触发子产品的字段保存,需补充对应逻辑
修正后的基础代码片段:
// Create field on product page admin add_action( 'woocommerce_product_options_general_product_data', 'tpc_woocommerce_product_custom_fields' ); function tpc_woocommerce_product_custom_fields () { woocommerce_wp_text_input( array( 'id' => '_custom_product_merch_shop_cle', 'label' => esc_html__( 'Merch Shop Art', 'woocommerce' ), 'placeholder' => esc_html__( 'Enter CLE here', 'woocommerce' ), 'desc_tip' => true, 'description' => esc_html__( 'Use to add CLE# for merch shops', 'woocommerce' ), ) ); } // Save field value for simple products add_action( 'woocommerce_process_product_meta', 'tpc_woocommerce_product_custom_fields_save' ); function tpc_woocommerce_product_custom_fields_save( $post_id ){ $custom_field_value = isset( $_POST['_custom_product_merch_shop_cle'] ) ? wc_clean( wp_unslash( $_POST['_custom_product_merch_shop_cle'] ) ) : ''; update_post_meta( $post_id, '_custom_product_merch_shop_cle', $custom_field_value ); } // 新增:兼容可变产品子变体的字段保存 add_action( 'woocommerce_save_product_variation', 'tpc_woocommerce_variation_custom_fields_save', 10, 2 ); function tpc_woocommerce_variation_custom_fields_save( $variation_id, $i ) { $custom_field_value = isset( $_POST['_custom_product_merch_shop_cle'][$i] ) ? wc_clean( wp_unslash( $_POST['_custom_product_merch_shop_cle'][$i] ) ) : ''; update_post_meta( $variation_id, '_custom_product_merch_shop_cle', $custom_field_value ); }
2. 将产品字段值保存到订单项元数据(核心需求)
使用woocommerce_add_order_item_meta钩子,在订单创建时将下单时刻的产品/变体字段值复制到订单项元数据中,确保后续修改产品字段不会影响历史订单:
// 保存产品自定义字段到订单项元数据 add_action( 'woocommerce_add_order_item_meta', 'tpc_save_custom_field_to_order_item', 10, 3 ); function tpc_save_custom_field_to_order_item( $item_id, $values, $cart_item_key ) { // 优先获取变体的字段值,无变体则取父产品值 $target_id = $values['variation_id'] > 0 ? $values['variation_id'] : $values['product_id']; $cle_value = get_post_meta( $target_id, '_custom_product_merch_shop_cle', true ); if ( ! empty( $cle_value ) ) { wc_add_order_item_meta( $item_id, '_custom_product_merch_shop_cle', $cle_value ); } }
3. 后台订单详情显示订单项字段值
添加以下代码,在后台订单的订单项详情中仅当存在值时显示该字段:
// 后台订单详情显示订单项的CLE字段 add_action( 'woocommerce_admin_order_item_values', 'tpc_display_custom_field_in_admin_order', 10, 3 ); function tpc_display_custom_field_in_admin_order( $product, $item, $item_id ) { $cle_value = get_post_meta( $item_id, '_custom_product_merch_shop_cle', true ); if ( ! empty( $cle_value ) ) { ?> <tr> <td class="label">Merch Shop CLE#:</td> <td><?php echo esc_html( $cle_value ); ?></td> </tr> <?php } }
完整代码整合
将所有代码添加到主题的functions.php文件或自定义插件中即可:
// Create field on product page admin add_action( 'woocommerce_product_options_general_product_data', 'tpc_woocommerce_product_custom_fields' ); function tpc_woocommerce_product_custom_fields () { woocommerce_wp_text_input( array( 'id' => '_custom_product_merch_shop_cle', 'label' => esc_html__( 'Merch Shop Art', 'woocommerce' ), 'placeholder' => esc_html__( 'Enter CLE here', 'woocommerce' ), 'desc_tip' => true, 'description' => esc_html__( 'Use to add CLE# for merch shops', 'woocommerce' ), ) ); } // Save field value for simple products add_action( 'woocommerce_process_product_meta', 'tpc_woocommerce_product_custom_fields_save' ); function tpc_woocommerce_product_custom_fields_save( $post_id ){ $custom_field_value = isset( $_POST['_custom_product_merch_shop_cle'] ) ? wc_clean( wp_unslash( $_POST['_custom_product_merch_shop_cle'] ) ) : ''; update_post_meta( $post_id, '_custom_product_merch_shop_cle', $custom_field_value ); } // Save field value for product variations add_action( 'woocommerce_save_product_variation', 'tpc_woocommerce_variation_custom_fields_save', 10, 2 ); function tpc_woocommerce_variation_custom_fields_save( $variation_id, $i ) { $custom_field_value = isset( $_POST['_custom_product_merch_shop_cle'][$i] ) ? wc_clean( wp_unslash( $_POST['_custom_product_merch_shop_cle'][$i] ) ) : ''; update_post_meta( $variation_id, '_custom_product_merch_shop_cle', $custom_field_value ); } // Save custom field to order item meta add_action( 'woocommerce_add_order_item_meta', 'tpc_save_custom_field_to_order_item', 10, 3 ); function tpc_save_custom_field_to_order_item( $item_id, $values, $cart_item_key ) { $target_id = $values['variation_id'] > 0 ? $values['variation_id'] : $values['product_id']; $cle_value = get_post_meta( $target_id, '_custom_product_merch_shop_cle', true ); if ( ! empty( $cle_value ) ) { wc_add_order_item_meta( $item_id, '_custom_product_merch_shop_cle', $cle_value ); } } // Display custom field in admin order details add_action( 'woocommerce_admin_order_item_values', 'tpc_display_custom_field_in_admin_order', 10, 3 ); function tpc_display_custom_field_in_admin_order( $product, $item, $item_id ) { $cle_value = get_post_meta( $item_id, '_custom_product_merch_shop_cle', true ); if ( ! empty( $cle_value ) ) { ?> <tr> <td class="label">Merch Shop CLE#:</td> <td><?php echo esc_html( $cle_value ); ?></td> </tr> <?php } }
关键说明
- 订单项元数据会在订单创建时复制产品当时的字段值,后续修改产品的CLE字段不会影响已生成的订单数据,满足历史数据保留需求
- 代码兼容简单产品和可变产品的子变体,确保所有产品类型的字段值都能正确保存和传递
- 后台仅在订单项存在CLE值时才显示对应内容,避免冗余信息
内容的提问来源于stack exchange,提问作者Two Pines Brian
相关产品推荐
相关产品推荐

