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

如何在WooCommerce经典结账页面拦截非配送区域邮编?

WooCommerce经典结账页面邮编配送验证实现指引

我们可以从前端实时拦截和后端强制验证两个层面入手,既给用户即时反馈,又防止恶意绕过前端限制,完全适配你现有的DeliveryChecker API逻辑。


1. 前端实时验证:用户输入时即时检查

目标是监听结账页面的邮编输入框,调用DeliveryChecker API验证,实时提示用户并禁用结账按钮。

步骤1:添加自定义脚本加载逻辑

在主题的functions.php中加入以下代码,确保只在结账页面加载验证脚本:

// 加载结账页面邮编验证脚本
add_action( 'wp_enqueue_scripts', 'checkout_postcode_validation_loader' );
function checkout_postcode_validation_loader() {
    // 仅在结账主页面加载(排除订单完成等端点)
    if ( is_checkout() && ! is_wc_endpoint_url() ) {
        wp_enqueue_script( 
            'checkout-postcode-validator', 
            get_stylesheet_directory_uri() . '/js/checkout-postcode-validator.js', 
            array( 'jquery' ), 
            '1.0', 
            true 
        );
        // 传递配置参数给前端
        wp_localize_script( 'checkout-postcode-validator', 'PostcodeConfig', array(
            'registerUrl' => '/register-your-interest-261/',
            'widgetId'    => '166f5152dc8d7b'
        ) );
    }
}

步骤2:编写前端验证逻辑

在主题目录下创建js/checkout-postcode-validator.js,写入以下代码:

jQuery(document).ready(function($) {
    // 加载DeliveryChecker官方脚本(如果未加载)
    if (typeof DeliveryChecker === 'undefined') {
        const script = document.createElement('script');
        script.type = 'text/javascript';
        script.async = true;
        script.src = `https://cdn.deliverychecker.co/api/v1/js/${PostcodeConfig.widgetId}.js`;
        document.head.appendChild(script);
    }

    // 核心元素选择器(WooCommerce默认字段ID,自定义过的话要对应修改)
    const postcodeField = $('#billing_postcode');
    const checkoutBtn = $('button[name="woocommerce_checkout_place_order"]');
    const errorMsg = `<div class="postcode-error" style="color:red;margin:10px 0;">该邮编不在配送范围内,请<a href="${PostcodeConfig.registerUrl}">登记意向</a></div>`;

    // 调用API验证邮编
    function checkPostcodeValidity(postcode) {
        $.ajax({
            url: 'https://cdn.deliverychecker.co/api/v1/check', // 确认实际API端点,可通过抓包现有组件获取
            method: 'POST',
            data: {
                widget_id: PostcodeConfig.widgetId,
                postcode: postcode.trim()
            },
            success: function(res) {
                // 复用你现有组件的判断逻辑:检查返回信息是否包含"Sorry"
                if (res.message?.startsWith('Sorry')) {
                    $('.postcode-error').length || postcodeField.after(errorMsg);
                    checkoutBtn.prop('disabled', true);
                    // 可选:自动跳转到意向页(和你现有逻辑一致)
                    // setTimeout(() => window.location = PostcodeConfig.registerUrl, 3000);
                } else {
                    $('.postcode-error').remove();
                    checkoutBtn.prop('disabled', false);
                }
            },
            error: function() {
                // API调用失败时,默认允许用户继续(可根据业务调整)
                $('.postcode-error').remove();
                checkoutBtn.prop('disabled', false);
            }
        });
    }

    // 输入框失去焦点时触发验证
    postcodeField.on('blur', function() {
        const postcode = $(this).val();
        postcode.length >= 5 && checkPostcodeValidity(postcode); // 英国邮编至少5位,按需调整
    });

    // 输入过程中延迟验证(避免频繁调用API)
    let validateTimer;
    postcodeField.on('input', function() {
        clearTimeout(validateTimer);
        const postcode = $(this).val();
        if (postcode.length >= 5) {
            validateTimer = setTimeout(() => checkPostcodeValidity(postcode), 500);
        } else {
            $('.postcode-error').remove();
            checkoutBtn.prop('disabled', false);
        }
    });
});

2. 后端强制验证:防止绕过前端限制

前端验证可以被篡改,必须在订单提交前做后端校验,用WooCommerce钩子实现:

add_action( 'woocommerce_checkout_process', 'backend_postcode_validation' );
function backend_postcode_validation() {
    $postcode = isset($_POST['billing_postcode']) ? sanitize_text_field($_POST['billing_postcode']) : '';
    if (empty($postcode)) return;

    // 调用DeliveryChecker API做后端验证
    $widgetId = '166f5152dc8d7b';
    $apiUrl = 'https://cdn.deliverychecker.co/api/v1/check';
    $response = wp_remote_post($apiUrl, array(
        'body' => array(
            'widget_id' => $widgetId,
            'postcode'  => $postcode
        ),
        'timeout' => 10
    ));

    if (is_wp_error($response)) {
        wc_add_notice('邮编验证失败,请稍后重试', 'error');
        return;
    }

    $responseData = json_decode(wp_remote_retrieve_body($response), true);
    // 同样复用现有逻辑判断
    if (isset($responseData['message']) && strpos($responseData['message'], 'Sorry') !== false) {
        wc_add_notice('该邮编不在配送范围内,请<a href="/register-your-interest-261/">登记意向</a>', 'error');
    }
}

3. 注意事项

  • 确认API端点:如果上述/api/v1/check不对,可以通过浏览器开发者工具抓包你现有组件的请求,获取真实的API地址和参数格式。
  • 字段适配:如果你的结账页面用了自定义邮编字段ID,要修改JS中的选择器(比如#billing_postcode换成你的字段ID)。
  • 邮编格式:根据目标地区调整输入长度判断(比如国内邮编是6位)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 17:45:00