WooCommerce报价结账保留国家/非报价IP定位限制代码求助
问题背景
环境信息
- WooCommerce版本:3.6.2
- WordPress版本:5.1.1
- YITH WooCommerce Request A Quote Premium:2.1.7
需求目标
当客户通过YITH报价链接(示例:mysite/request-quote/?request_quote=330&status=accepted&raq_nonce=ad5c139f3d7a59993a4ff679d84de3a3&lang)结账时,保留报价中预设的账单/配送国家;其他场景下,通过GeoIP限制可选国家为客户所在国家,且禁用国家选择框的交互。
解决方案代码
// 修改结账字段:根据是否来自报价链接决定国家限制逻辑 add_filter( 'woocommerce_checkout_fields', 'vals_woo_checkout_country' ); function vals_woo_checkout_country( $fields ) { // 1. 判断是否来自YITH报价链接(通过URL参数识别) $is_from_quote = isset( $_GET['request_quote'] ) && isset( $_GET['status'] ) && $_GET['status'] === 'accepted'; // 2. 如果是报价结账场景,直接返回原字段(保留报价预设的国家) if ( $is_from_quote ) { return $fields; } // 3. 非报价场景:仅在结账页和订单支付页生效 if ( is_checkout() || is_wc_endpoint_url('order-pay') ) { // 获取GeoIP定位数据 $geoData = WC_Geolocation::geolocate_ip(); $country_code = $geoData['country']; $countries = WC()->countries->get_countries(); // 确保获取到有效的国家代码,否则 fallback到店铺基础国家 if ( empty( $country_code ) || !isset( $countries[$country_code] ) ) { $country_code = WC()->countries->get_base_country(); } // 限制账单国家为GeoIP定位的国家 $fields['billing']['billing_country'] = array( 'type' => 'select', 'label' => __('Country', 'woocommerce'), 'options' => array( $country_code => $countries[$country_code] ), 'class' => array( 'form-row-wide', 'address-field', 'update_totals_on_change' ) ); // 限制配送国家为GeoIP定位的国家 $fields['shipping']['shipping_country'] = array( 'type' => 'select', 'label' => __('Country', 'woocommerce'), 'options' => array( $country_code => $countries[$country_code] ), 'class' => array( 'form-row-wide', 'address-field', 'update_totals_on_change' ) ); } return $fields; } // 移除可选标签并禁用国家选择框的交互 add_action( 'wp_footer', 'remove_checkout_optional_fields_label_script' ); function remove_checkout_optional_fields_label_script() { // 仅在结账页(非端点页面)生效 if( ! ( is_checkout() && ! is_wc_endpoint_url() ) ) return; // 判断是否来自报价链接 $is_from_quote = isset( $_GET['request_quote'] ) && isset( $_GET['status'] ) && $_GET['status'] === 'accepted'; // 如果是报价场景,不执行禁用逻辑 if ( $is_from_quote ) { return; } $optional = ' <span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>'; ?> <script> jQuery(function($){ // 封装重复逻辑为函数 function applyCountryRestrictions() { $('#billing_country_field label > .optional').remove(); $('.woocommerce-checkout #billing_country_field').css('pointer-events', 'none'); $('#shipping_country_field label > .optional').remove(); $('.woocommerce-checkout #shipping_country_field').css('pointer-events', 'none'); } // 页面初始加载时执行 applyCountryRestrictions(); // 结账表单更新时再次执行,避免刷新后失效 $(document.body).on('update_checkout', applyCountryRestrictions); }); </script> <?php }
关键修改说明
- 报价场景识别:通过URL中的
request_quote和status=accepted参数精准判断客户是否来自报价链接,这种场景下直接保留原字段配置,不做任何限制。 - 修复逻辑判断:把原代码中错误的
(is_checkout()) && (is_wc_endpoint_url('order-pay'))改为is_checkout() || is_wc_endpoint_url('order-pay'),因为结账页和订单支付页是两个独立场景,不需要同时满足。 - 增加异常兜底:当GeoIP无法获取有效国家代码时,自动 fallback到店铺设置的基础国家,避免出现空选项的问题。
- 优化JS逻辑:将重复操作封装为函数,确保页面初始加载和结账表单更新时都能生效;同时在报价场景下跳过禁用交互的逻辑,让报价客户可以正常操作国家字段(如果需要完全锁定报价中的国家,也可以进一步调整这部分逻辑)。
内容的提问来源于stack exchange,提问作者KoolPal
相关产品推荐
相关产品推荐

