如何将WooCommerce产品对接门店仓储API实现库存价格自动同步
WooCommerce 对接线下仓储API同步产品问题修复方案
你当前代码的核心错误点
- 变量作用域错误:你在函数外部定义的
$sku、$url、$regular_price等变量,PHP函数内部默认无法直接访问全局变量,你也没有做变量引入,导致函数内这些变量都是未定义状态 - 逻辑顺序完全混乱:你还没调用API获取返回数据、也没有解析出接口返回的库存、价格字段,就直接用固定字符串去更新产品,根本没用到仓储API的真实数据
- 钩子逻辑冲突:你挂载的
woocommerce_update_product钩子是后台产品更新时才触发,你函数内又重新覆盖了传入的$product_id,完全浪费了钩子触发的上下文 - 无错误校验:没有判断API请求是否成功、返回值是否合法,接口报错、超时、返回非JSON格式时直接会触发PHP致命错误
- 无效代码冗余:你查询了
_sync_updated元字段不存在的产品ID列表,但是后续完全没有循环处理这段数据,属于完全无用的冗余代码
修复后的可运行代码
你可以根据需求选择两种触发方式:第一种是后台产品更新时触发单产品同步,第二种是加定时任务周期全量同步所有产品。
场景1:后台编辑产品时自动同步对应SKU的库存价格
add_action( 'woocommerce_update_product', 'sync_single_product_from_warehouse', 10, 1 ); function sync_single_product_from_warehouse( $product_id ) { $product = wc_get_product( $product_id ); if (!$product) return; // 拿到当前产品的SKU $sku = $product->get_sku(); if (empty($sku)) return; // 拼接API请求地址,替换成你自己的仓储API地址 $api_url = 'http://你的服务器IP:端口/api/pdd/ID=' . $sku; // 发起API请求 $request = wp_remote_get($api_url, array( 'timeout' => 120, )); // 判断请求是否成功 if (is_wp_error($request) || wp_remote_retrieve_response_code($request) != 200) { return; } // 解析返回数据 $body = wp_remote_retrieve_body($request); $api_data = json_decode($body, true); // 判断返回数据是否合法,字段名要和你实际接口返回的字段对应 if (!isset($api_data['SellRate'], $api_data['InventoryQuantity'])) { return; } // 拿接口数据更新产品 $regular_price = $api_data['SellRate']; $sale_price = $api_data['SellRate']; // 如果接口有单独的促销价字段就替换成对应字段 $quantity = intval($api_data['InventoryQuantity']); // 设置库存 $product->set_manage_stock(true); $product->set_stock_quantity($quantity); $product->set_stock_status($quantity > 0 ? 'instock' : 'outofstock'); // 设置价格 if ($regular_price == $sale_price) { $product->set_price($regular_price); $product->set_regular_price($regular_price); $product->set_sale_price(''); } else { $product->set_regular_price($regular_price); $product->set_sale_price($sale_price); $product->set_price($sale_price); } // 保存产品 $product->save(); }
场景2:全量同步所有产品的定时任务代码
// 注册1小时执行一次的定时任务 add_filter('cron_schedules', 'add_custom_cron_interval'); function add_custom_cron_interval($schedules) { $schedules['hourly_sync'] = array( 'interval' => 3600, 'display' => '每小时同步一次仓储产品' ); return $schedules; } // 注册定时任务钩子 add_action('wp', 'register_warehouse_sync_cron'); function register_warehouse_sync_cron() { if (!wp_next_scheduled('hourly_warehouse_sync_event')) { wp_schedule_event(time(), 'hourly_sync', 'hourly_warehouse_sync_event'); } } // 定时任务执行的同步逻辑 add_action('hourly_warehouse_sync_event', 'sync_all_products_from_warehouse'); function sync_all_products_from_warehouse() { // 每次最多处理200个产品,避免超时 $products = wc_get_products(array( 'limit' => 200, 'status' => 'publish', 'return' => 'objects', )); foreach ($products as $product) { $sku = $product->get_sku(); if (empty($sku)) continue; $api_url = 'http://你的服务器IP:端口/api/pdd/ID=' . $sku; $request = wp_remote_get($api_url, array('timeout' => 10)); if (is_wp_error($request) || wp_remote_retrieve_response_code($request) != 200) continue; $body = wp_remote_retrieve_body($request); $api_data = json_decode($body, true); if (!isset($api_data['SellRate'], $api_data['InventoryQuantity'])) continue; $regular_price = $api_data['SellRate']; $sale_price = $api_data['SellRate']; $quantity = intval($api_data['InventoryQuantity']); $product->set_manage_stock(true); $product->set_stock_quantity($quantity); $product->set_stock_status($quantity > 0 ? 'instock' : 'outofstock'); if ($regular_price == $sale_price) { $product->set_price($regular_price); $product->set_regular_price($regular_price); $product->set_sale_price(''); } else { $product->set_regular_price($regular_price); $product->set_sale_price($sale_price); $product->set_price($sale_price); } $product->save(); } }
使用注意事项
- 替换代码中的
http://你的服务器IP:端口为你实际的仓储API地址 - 确认你的仓储API返回字段和代码中取的
SellRate、InventoryQuantity一致,如果字段名不同要对应修改 - 如果你的API需要鉴权(比如token、密钥),要在
wp_remote_get的参数中加上对应的headers头信息 - 测试阶段可以先在本地环境运行,避免线上产品数据被错误修改
内容的提问来源于stack exchange,提问作者baghban251
相关产品推荐
相关产品推荐

