WooCommerce基于IP定位按国家设折扣功能故障求助
WooCommerce 基于IP定位国家折扣功能修复方案
原代码存在的问题
- ipstack API当前强制要求HTTPS请求,原代码用HTTP会导致请求失败
$_SERVER['REMOTE_ADDR']无法获取真实用户IP(若站点使用CDN或反向代理)- 未处理API返回的错误(如密钥无效、请求超限),直接访问
$data->country_code会触发PHP警告 - 每次获取价格都调用API,性能损耗大且易触发API请求限制
- 仅使用
woocommerce_product_get_price钩子,无法覆盖可变产品、购物车结算等场景
修复后的完整代码
function obtener_pais_por_ip() { // 先检查会话缓存,避免重复调用API if (isset($_SESSION['user_country_code'])) { return $_SESSION['user_country_code']; } $api_key = 'TU_CLAVE_DE_API'; // 获取真实用户IP,兼容CDN/代理场景 $user_ip = $_SERVER['REMOTE_ADDR']; if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && filter_var($_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP)) { $user_ip = $_SERVER['HTTP_X_FORWARDED_FOR']; } elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && filter_var($_SERVER['HTTP_CF_CONNECTING_IP'], FILTER_VALIDATE_IP)) { $user_ip = $_SERVER['HTTP_CF_CONNECTING_IP']; } // 使用HTTPS请求ipstack API $response = wp_remote_get("https://api.ipstack.com/$user_ip?access_key=$api_key"); if (is_wp_error($response)) { error_log('IP定位API请求失败: ' . $response->get_error_message()); return false; } $body = wp_remote_retrieve_body($response); $data = json_decode($body); // 检查API返回是否有效,是否包含错误 if (!$data || isset($data->error)) { error_log('IP定位API返回错误: ' . ($data->error->info ?? '未知错误')); return false; } // 检查country_code是否存在 if (empty($data->country_code)) { error_log('无法获取用户国家代码'); return false; } // 缓存国家代码到会话 $_SESSION['user_country_code'] = $data->country_code; return $data->country_code; } function aplicar_descuento_por_pais($price, $product) { // 后台管理页面不应用折扣 if (is_admin() && !defined('DOING_AJAX')) { return $price; } $user_country = obtener_pais_por_ip(); if (!$user_country) { return $price; } $countries_discount = array( 'ES' => 10, // 西班牙10%折扣 'US' => 15, // 美国15%折扣 // 添加更多国家及折扣比例 ); if (isset($countries_discount[$user_country])) { $discount_percent = $countries_discount[$user_country]; $discounted_price = $price * (1 - ($discount_percent / 100)); // 确保价格为合法数值,保留两位小数 return round($discounted_price, 2); } return $price; } // 注册多个钩子覆盖不同场景 add_filter('woocommerce_product_get_price', 'aplicar_descuento_por_pais', 10, 2); add_filter('woocommerce_product_variation_get_price', 'aplicar_descuento_por_pais', 10, 2); add_filter('woocommerce_get_price', 'aplicar_descuento_por_pais', 10, 2); add_filter('woocommerce_cart_item_price', 'aplicar_descuento_por_pais', 10, 2);
注意事项
- 替换
TU_CLAVE_DE_API为你的ipstack有效API密钥 - 若使用其他CDN,需根据CDN文档调整真实IP的获取方式(如阿里云CDN用
HTTP_X_REAL_IP) - 确保PHP会话支持正常开启(WooCommerce通常默认已开启)
- 可通过WordPress错误日志(wp-content/debug.log)查看API请求问题,需开启WP_DEBUG模式
- 测试时可手动修改
$user_country为目标国家代码(如'ES'),验证折扣是否生效
内容的提问来源于stack exchange,提问作者Cesar Hidalgo
相关产品推荐
相关产品推荐

