Skip to content

Instantly share code, notes, and snippets.

@vapvarun
Created August 29, 2025 17:32
Show Gist options
  • Select an option

  • Save vapvarun/f56dc6c3b8945cf74785e9653bd0fd27 to your computer and use it in GitHub Desktop.

Select an option

Save vapvarun/f56dc6c3b8945cf74785e9653bd0fd27 to your computer and use it in GitHub Desktop.

WBCOM – Geo Restrict THCA (AU/NZ via Cloudflare)

Hide, redirect, and block checkout for a WooCommerce category when visitors are from Australia or New Zealand using Cloudflare’s CF-IPCountry.

What it does

  • Hides products in the restricted category from shop, archives, search, shortcodes, widgets, blocks.
  • Redirects AU/NZ visitors away from the category page and any single product in that category → to the Shop page.
  • Blocks add-to-cart via any method (buttons, AJAX, ?add-to-cart=ID, REST).
  • Cleans up saved carts and double-checks at checkout.
  • Adds Vary: CF-IPCountry to keep caches/CDNs from mixing countries.

Requirements

  • Site proxied by Cloudflare.
  • Cloudflare Network → IP Geolocation enabled (adds CF-IPCountry header).
  • WordPress + WooCommerce.

Quick install (as a plugin)

  1. Download wbcom-geo-restrict-thca-au-nz.php.
  2. Zip it (optional) or place directly into /wp-content/plugins/.
  3. Activate WBCOM – Geo Restrict THCA (AU/NZ via Cloudflare) in Plugins.

Configure

In the plugin header:

const WBCOM_RESTRICTED_CAT_ID   = 369;           // product_cat term_id
const WBCOM_RESTRICTED_CAT_SLUG = 'thca-flower'; // product_cat slug
<?php
/**
* Plugin Name: WBCOM – Geo Restrict THCA (AU/NZ via Cloudflare)
* Description: Hides a WooCommerce category, redirects its pages, and blocks add-to-cart/checkout for AU & NZ using CF-IPCountry.
* Author: Wbcom Designs
* Version: 1.0.0
* Requires at least: 5.8
* Requires PHP: 7.4
*/
if ( ! defined( 'ABSPATH' ) ) exit;
/** ============ CONFIG ============ */
const WBCOM_BLOCKED_COUNTRIES = [ 'AU', 'NZ' ];
const WBCOM_RESTRICTED_CAT_ID = 369; // product_cat term_id
const WBCOM_RESTRICTED_CAT_SLUG = 'thca-flower'; // product_cat slug
/** Geo check (Cloudflare) */
function wbcom_geo_blocked(): bool {
$cc = $_SERVER['HTTP_CF_IPCOUNTRY'] ?? '';
return in_array( strtoupper( trim( $cc ) ), WBCOM_BLOCKED_COUNTRIES, true );
}
/** Resolve the restricted category term IDs */
function wbcom_restricted_term_ids(): array {
$ids = [];
if ( WBCOM_RESTRICTED_CAT_ID ) {
$t = get_term( WBCOM_RESTRICTED_CAT_ID, 'product_cat' );
if ( $t && ! is_wp_error( $t ) ) $ids[] = (int) $t->term_id;
}
if ( WBCOM_RESTRICTED_CAT_SLUG ) {
$t = get_term_by( 'slug', WBCOM_RESTRICTED_CAT_SLUG, 'product_cat' );
if ( $t && ! is_wp_error( $t ) ) $ids[] = (int) $t->term_id;
}
return array_unique( array_filter( $ids ) );
}
/** Is this product (or its parent) in the restricted category? */
function wbcom_is_restricted_product( $product_id ): bool {
if ( ! $product_id ) return false;
$ids = wbcom_restricted_term_ids();
if ( ! $ids ) return false;
if ( has_term( $ids, 'product_cat', (int) $product_id ) ) return true;
$product = wc_get_product( $product_id );
if ( $product && $product->is_type( 'variation' ) ) {
$parent_id = $product->get_parent_id();
if ( $parent_id && has_term( $ids, 'product_cat', $parent_id ) ) return true;
}
return false;
}
/** 1) Hide from main loops: shop, archives, search */
add_action( 'pre_get_posts', function( $q ) {
if ( is_admin() || ! $q->is_main_query() || ! wbcom_geo_blocked() ) return;
if ( $q->is_post_type_archive( 'product' ) || $q->is_tax( [ 'product_cat', 'product_tag' ] ) || $q->is_search() ) {
$ids = wbcom_restricted_term_ids();
if ( $ids ) {
$tax_query = (array) $q->get( 'tax_query' );
$tax_query[] = [
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $ids,
'operator' => 'NOT IN',
];
$q->set( 'tax_query', $tax_query );
}
}
});
/** 2) Hide from WooCommerce product queries (shortcodes, widgets, blocks) */
add_action( 'woocommerce_product_query', function( $wcq ) {
if ( ! wbcom_geo_blocked() ) return;
$ids = wbcom_restricted_term_ids();
if ( ! $ids ) return;
$tax_query = (array) $wcq->get( 'tax_query' );
$tax_query[] = [
'taxonomy' => 'product_cat',
'field' => 'term_id',
'terms' => $ids,
'operator' => 'NOT IN',
];
$wcq->set( 'tax_query', $tax_query );
});
/** 3) Redirect AU/NZ off the restricted category page and its products */
add_action( 'template_redirect', function() {
if ( ! wbcom_geo_blocked() ) return;
$ids = wbcom_restricted_term_ids();
if ( ! $ids ) return;
// Category page
if ( is_product_category( $ids ) ) {
wp_safe_redirect( wc_get_page_permalink( 'shop' ) );
exit;
}
// Single product page
if ( is_product() ) {
global $post;
if ( $post && wbcom_is_restricted_product( $post->ID ) ) {
wp_safe_redirect( wc_get_page_permalink( 'shop' ) );
exit;
}
}
});
/** 4) Block add-to-cart (?add-to-cart=ID, AJAX, buttons, API) */
add_filter( 'woocommerce_add_to_cart_validation', function( $passed, $product_id, $qty, $variation_id = 0 ) {
if ( ! wbcom_geo_blocked() ) return $passed;
$check_id = $variation_id ?: $product_id;
if ( wbcom_is_restricted_product( $check_id ) ) {
wc_add_notice( __( 'Sorry, this product is not available in your region.', 'wbcom' ), 'error' );
return false;
}
return $passed;
}, 10, 4 );
/** 5) Sweep cart from session (saved carts, pre-existing items) */
add_action( 'woocommerce_cart_loaded_from_session', function( $cart ) {
if ( ! wbcom_geo_blocked() || ! $cart ) return;
$removed = false;
foreach ( $cart->get_cart() as $key => $item ) {
$pid = $item['variation_id'] ?: $item['product_id'];
if ( wbcom_is_restricted_product( $pid ) ) {
$cart->remove_cart_item( $key );
$removed = true;
}
}
if ( $removed ) {
wc_add_notice( __( 'Some items were removed because they are not available in your region.', 'wbcom' ), 'notice' );
}
});
/** 6) Final guard at checkout */
add_action( 'woocommerce_check_cart_items', function() {
if ( ! wbcom_geo_blocked() ) return;
$blocked_found = false;
foreach ( WC()->cart->get_cart() as $key => $item ) {
$pid = $item['variation_id'] ?: $item['product_id'];
if ( wbcom_is_restricted_product( $pid ) ) {
WC()->cart->remove_cart_item( $key );
$blocked_found = true;
}
}
if ( $blocked_found ) {
wc_add_notice( __( 'Your cart was updated because one or more items are not available in your region.', 'wbcom' ), 'error' );
}
});
/** 7) Cache safety for CF/APO and other caches */
add_action( 'send_headers', function() {
if ( headers_sent() ) return;
header( 'Vary: CF-IPCountry' );
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment