You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 = '&nbsp;<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
}

关键修改说明
  1. 报价场景识别:通过URL中的request_quote和status=accepted参数精准判断客户是否来自报价链接,这种场景下直接保留原字段配置,不做任何限制。
  2. 修复逻辑判断:把原代码中错误的(is_checkout()) && (is_wc_endpoint_url('order-pay'))改为is_checkout() || is_wc_endpoint_url('order-pay'),因为结账页和订单支付页是两个独立场景,不需要同时满足。
  3. 增加异常兜底:当GeoIP无法获取有效国家代码时,自动 fallback到店铺设置的基础国家,避免出现空选项的问题。
  4. 优化JS逻辑:将重复操作封装为函数,确保页面初始加载和结账表单更新时都能生效;同时在报价场景下跳过禁用交互的逻辑,让报价客户可以正常操作国家字段(如果需要完全锁定报价中的国家,也可以进一步调整这部分逻辑)。

内容的提问来源于stack exchange,提问作者KoolPal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:09:50