通过API设置WooCommerce订单自定义字段值失败问题排查
问题描述
在WooCommerce后台订单页面添加了自定义字段_order_pdf_link,目前已实现的正常功能包括:
- 后台订单详情页能显示该字段
- 后台修改字段值后,能正确保存到post meta
- REST API的GET请求能通过自定义响应属性返回该字段值
但调用PUT Order API时,通过metadata字段设置_order_pdf_link后,API返回和后续GET请求的metadata里能看到该字段,可后台自定义字段不显示,自定义API响应属性也无返回值。核心原因是WooCommerce REST API默认会把metadata字段的内容存储到订单的metadata数组,而非我们代码依赖的post meta。
解决方案
需要添加API请求的同步逻辑,让_order_pdf_link在post meta和订单metadata数组间双向同步:
1. 同步API PUT请求的metadata到post meta
添加钩子,当API更新订单metadata时,自动将_order_pdf_link的值同步到post meta:
add_action('woocommerce_rest_update_order_metadata', function($order_id, $meta_key, $meta_value) { if ($meta_key === '_order_pdf_link') { update_post_meta($order_id, '_order_pdf_link', esc_url_raw($meta_value)); } }, 10, 3);
2. 同步post meta到API返回的metadata数组
如果需要让API返回的metadata字段也包含post meta里的_order_pdf_link(保持前后端数据一致),添加以下代码:
add_filter('woocommerce_rest_order_prepare_metadata', function($metadata, $order) { $pdf_url = get_post_meta($order->get_id(), '_order_pdf_link', true); if (!empty($pdf_url)) { // 检查是否已存在该字段,避免重复 $exists = false; foreach ($metadata as &$meta) { if ($meta['key'] === '_order_pdf_link') { $meta['value'] = $pdf_url; $exists = true; break; } } if (!$exists) { $metadata[] = [ 'key' => '_order_pdf_link', 'value' => $pdf_url ]; } } return $metadata; }, 10, 2);
完整整合代码
将原有代码和新增同步逻辑整合后的完整代码:
// 后台订单详情显示自定义字段 add_action('woocommerce_admin_order_data_after_order_details', function($order){ $pdf_url = get_post_meta($order->get_id(), '_order_pdf_link', true); echo '<p></p><br>'; echo ' <p style="margin-top:25px;"><strong>Report File URL:</strong></p> <input type="text" id="_order_pdf_link" name="_order_pdf_link" style="width:100%;" value="' . esc_attr($pdf_url) . '" placeholder="Paste file URL (PDF, image, etc.) here" />'; }); // 后台保存自定义字段到post meta add_action('woocommerce_process_shop_order_meta', function($order_id){ if (isset($_POST['_order_pdf_link'])) { update_post_meta($order_id, '_order_pdf_link', esc_url_raw($_POST['_order_pdf_link'])); } }); // REST API GET请求返回自定义字段 function prefix_wc_rest_prepare_order_object( $response, $object, $request ) { $reference_meta_field = get_post_meta($object->get_id(), '_order_pdf_link', true) ?: ''; $response->data['_order_pdf_link'] = $reference_meta_field; return $response; } add_filter( 'woocommerce_rest_prepare_shop_order_object', 'prefix_wc_rest_prepare_order_object', 10, 3 ); // REST API PUT请求同步metadata到post meta add_action('woocommerce_rest_update_order_metadata', function($order_id, $meta_key, $meta_value) { if ($meta_key === '_order_pdf_link') { update_post_meta($order_id, '_order_pdf_link', esc_url_raw($meta_value)); } }, 10, 3); // 同步post meta到API返回的metadata数组 add_filter('woocommerce_rest_order_prepare_metadata', function($metadata, $order) { $pdf_url = get_post_meta($order->get_id(), '_order_pdf_link', true); if (!empty($pdf_url)) { $exists = false; foreach ($metadata as &$meta) { if ($meta['key'] === '_order_pdf_link') { $meta['value'] = $pdf_url; $exists = true; break; } } if (!$exists) { $metadata[] = [ 'key' => '_order_pdf_link', 'value' => $pdf_url ]; } } return $metadata; }, 10, 2);
逻辑说明
woocommerce_rest_update_order_metadata钩子在API更新订单metadata时触发,判断字段名后同步更新到post meta,确保后台能读取到值woocommerce_rest_order_prepare_metadata钩子负责准备API返回的metadata数组,把post meta的值同步进去,保证前后端数据一致
内容的提问来源于stack exchange,提问作者Sutra Wellness
相关产品推荐
相关产品推荐

