匹配厂商与买家ZIP码显示WooCommerce特殊配送选项故障排查
WooCommerce 厂商ZIP与客户配送ZIP匹配时显示特殊配送价格的代码修复
我已为WooCommerce产品添加自定义字段以存储厂商ZIP码,该功能运行正常。现需求为:当产品对应的厂商ZIP码与客户的配送ZIP码匹配时,显示特殊配送价格。以下是我编写的代码,但该代码无法正常生效,请问需要对代码做出哪些修改?
// Add a field to enter the manufacturer's ZIP code on the product page add_action('woocommerce_product_options_general_product_data', 'dodaj_zip_proizvodjaca'); function dodaj_zip_proizvodjaca() { woocommerce_wp_text_input(array( 'id' => '_zip_proizvodjaca', 'label' => 'ZIP proizvođača', 'desc_tip' => true, 'description' => 'Unesite ZIP kod proizvođača ovog proizvoda.', )); } // Save the manufacturer ZIP code value add_action('woocommerce_process_product_meta', 'sacuvaj_zip_proizvodjaca'); function sacuvaj_zip_proizvodjaca($post_id) { $zip = isset($_POST['_zip_proizvodjaca']) ? sanitize_text_field($_POST['_zip_proizvodjaca']) : ''; update_post_meta($post_id, '_zip_proizvodjaca', $zip); } // Add a separate shipping method if the ZIP codes are the same add_filter('woocommerce_package_rates', 'poseban_nacin_dostave_za_isti_zip', 10, 2); function poseban_nacin_dostave_za_isti_zip($rates, $package) { $isti_zip = false; $zip_kupca = WC()->customer->get_shipping_postcode(); foreach ($package['contents'] as $item_id => $values) { $product_id = $values['product_id']; $zip_proizvodjaca = get_post_meta($product_id, '_zip_proizvodjaca', true); if ($zip_proizvodjaca && $zip_kupca && $zip_proizvodjaca == $zip_kupca) { $isti_zip = true; break; } } if ($isti_zip) { // Add a special shipping method $rates['poseban_nacin_dostave'] = array( 'id' => 'poseban_nacin_dostave', 'label' => 'Specijalna dostava za isti ZIP', 'cost' => 180, // besplatna dostava ili cena po izboru 'taxes' => '', 'calc_tax' => 'per_order', ); } return $rates; }
代码问题及修改方案
1. 替换过时的产品元数据保存钩子
woocommerce_process_product_meta已被弃用,改用woocommerce_admin_process_product_object直接操作产品对象,避免post_id相关的潜在问题:
// Save the manufacturer ZIP code value add_action('woocommerce_admin_process_product_object', 'sacuvaj_zip_proizvodjaca'); function sacuvaj_zip_proizvodjaca($product) { $zip = isset($_POST['_zip_proizvodjaca']) ? sanitize_text_field($_POST['_zip_proizvodjaca']) : ''; $product->update_meta_data('_zip_proizvodjaca', $zip); $product->save(); }
2. 正确创建配送费率对象
不能直接向$rates数组添加普通数组,必须创建WC_Shipping_Rate对象才符合WooCommerce的规范:
3. 可靠获取客户配送ZIP码
优先从当前包裹的配送地址中获取ZIP,避免客户未设置默认配送地址时的空值问题:
4. 清除配送费率缓存
修改后需要清除缓存,确保配送方式实时更新。
修改后的完整代码
// Add a field to enter the manufacturer's ZIP code on the product page add_action('woocommerce_product_options_general_product_data', 'dodaj_zip_proizvodjaca'); function dodaj_zip_proizvodjaca() { woocommerce_wp_text_input(array( 'id' => '_zip_proizvodjaca', 'label' => 'ZIP proizvođača', 'desc_tip' => true, 'description' => 'Unesite ZIP kod proizvođača ovog proizvoda.', )); } // Save the manufacturer ZIP code value add_action('woocommerce_admin_process_product_object', 'sacuvaj_zip_proizvodjaca'); function sacuvaj_zip_proizvodjaca($product) { $zip = isset($_POST['_zip_proizvodjaca']) ? sanitize_text_field($_POST['_zip_proizvodjaca']) : ''; $product->update_meta_data('_zip_proizvodjaca', $zip); $product->save(); } // Add a separate shipping method if the ZIP codes are the same add_filter('woocommerce_package_rates', 'poseban_nacin_dostave_za_isti_zip', 10, 2); function poseban_nacin_dostave_za_isti_zip($rates, $package) { $isti_zip = false; // 从包裹地址获取配送ZIP,更可靠 $zip_kupca = isset($package['destination']['postcode']) ? sanitize_text_field($package['destination']['postcode']) : ''; foreach ($package['contents'] as $item_id => $values) { $product = $values['data']; $zip_proizvodjaca = $product->get_meta('_zip_proizvodjaca', true); if (!empty($zip_proizvodjaca) && !empty($zip_kupca) && $zip_proizvodjaca === $zip_kupca) { $isti_zip = true; break; } } if ($isti_zip) { // 创建合法的WC_Shipping_Rate对象 $special_rate = new WC_Shipping_Rate( 'poseban_nacin_dostave', 'Specijalna dostava za isti ZIP', 180, array(), 'poseban_nacin_dostave' ); // 添加到费率数组 $rates['poseban_nacin_dostave'] = $special_rate; } // 清除缓存确保实时更新 foreach ($rates as $rate_key => $rate) { $rates[$rate_key]->set_cache_key(''); } return $rates; }
额外注意事项
- 测试前请清空WooCommerce配送缓存(WooCommerce > 状态 > 工具 > 清除配送缓存)
- 确保客户已在购物车/结账页面填写配送地址,否则无法获取ZIP码
- 若需隐藏其他配送方式,可在
$isti_zip为true时先清空$rates数组,再添加特殊配送方式
内容的提问来源于stack exchange,提问作者Floooxy Design
相关产品推荐
相关产品推荐

