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

WooCommerce:如何基于地理定位国家拦截特定产品的直接访问

Solution: Block Direct Access to Specific WooCommerce Products by Country

Hey there! I see you’ve already nailed the geolocation-based product hiding for archive, category, and search pages—great work! The direct product page access loophole is a common snag, but we can fix that with a simple addition to your existing code.

The Problem

Your current code hides restricted products from listing pages, but users can still reach them via direct URLs. We need to intercept requests to those single product pages and block access based on the user’s country.

The Fix

We’ll use the template_redirect hook (which fires right before WordPress loads the page template) to add a check for single product pages. Here’s the updated code:

// Existing code: Hide products on archive/search pages
add_action( 'woocommerce_product_query', 'bbloomer_hide_product_if_country_new', 9999, 2 );
function bbloomer_hide_product_if_country_new( $q, $query ) {
    if ( is_admin() ) return;
    $location = WC_Geolocation::geolocate_ip();
    $hide_products = array( 17550, 32 );
    $country = $location['country'];
    if ( $country === "US" ) {
        $q->set( 'post__not_in', $hide_products );
    }
}

// New code: Block direct access to restricted single product pages
add_action( 'template_redirect', 'bbloomer_block_direct_product_access_by_country' );
function bbloomer_block_direct_product_access_by_country() {
    // Exit if we're not on a single product page or in the admin area
    if ( ! is_product() || is_admin() ) return;

    $location = WC_Geolocation::geolocate_ip();
    $hide_products = array( 17550, 32 );
    $country = $location['country'];
    $current_product_id = get_the_ID();

    // Check if user is from restricted country and accessing a blocked product
    if ( $country === "US" && in_array( $current_product_id, $hide_products ) ) {
        // Option 1: Redirect to shop page with an error notice (user-friendly)
        wc_add_notice( __( 'This product is not available in your country.', 'woocommerce' ), 'error' );
        wp_redirect( get_permalink( wc_get_page_id( 'shop' ) ) );
        exit;

        // Option 2: Show 404 error page (makes product seem non-existent)
        // global $wp_query;
        // $wp_query->set_404();
        // status_header( 404 );
        // get_template_part( 404 );
        // exit;
    }
}

How It Works

  1. Hook into template_redirect: This lets us intercept the request early, before the product page loads.
  2. Check Context: We first confirm we’re on a single product page and not in the admin dashboard.
  3. Reuse Geolocation Logic: We pull the user’s country using the same WC_Geolocation method as your existing code.
  4. Block Access: If the user is from the restricted country (US) and viewing a blocked product, we either:
    • Redirect them to the shop page with a clear error notice (Option 1, recommended for user experience), or
    • Trigger a 404 error to make the product appear unavailable entirely (Option 2, uncomment the lines to use this).

Pro Tip to Avoid Duplication

To keep your code clean, define the restricted products as a constant so you don’t have to update the array in two places:

// Define once at the top of your functions.php
define( 'RESTRICTED_PRODUCTS', array( 17550, 32 ) );

// Then use RESTRICTED_PRODUCTS in both functions instead of the array

Testing

Make sure to test this with a VPN to simulate being in the US—try accessing the direct product URL to confirm it blocks access as expected.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 09:42:42