Disable check out in WooCommerce for specific countries

WooCommerce Logo

I wanted to write a plugin that would disable the ability to check out within WooCommerce for specific countries; this utilizes the ipstack service but could also be done via the GeoIP with Nginx and/or PHP.

The plugin itself is more or less a proof of concept and could certainly be expanded upon. The overall usage as shown below is specific to item in the US; you would change the category of the product to “US-Only“, and any incoming IP that shows as being from the US country code will enable the plugin to disallow the check out button as well as providing an error message, so the visitor knows to remove said items.

<?php
/*
Plugin Name: WooCommerce disable product by category with country detection
Description: Simple plugin that will disable checkout for specific WooCommerce categories based on the visitor's country.
Version: 0.2.1
Author: Shelby DeNike
Author URI: https://denike.io
Text Domain: woocommerce-disable-product-by-category-with-country-detection
*/

// Set variables
$ipstack_key = "XXXXXX";

// Get visitors IP address
$ip_address = $_SERVER['REMOTE_ADDR'];

// Start IPSTack fucntionality. Initiate API Request
$ch = curl_init('http://api.ipstack.com/'. $ip_address .'?access_key=' . $ipstack_key .'');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

// Store API results
$json = curl_exec($ch);
curl_close($ch);

// Decode the JSON reponse and store API Rsults
$api_result = json_decode($json, true);
$visitor_country = $api_result['country_code'];

if ( $visitor_country != "US" ) {
// Check items in cart function
add_action( 'woocommerce_before_cart', 'systm_check_category_in_cart' );

// Disable checkout button function
function systm_disable_checkout_button_no_shipping() {
        remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
        echo '<a href="#" class="checkout-button button alt">Check out not available.</a>';
}

// Function to check categories of products, and display error message if matching item found.
function systm_check_category_in_cart() {
	$cat_in_cart = false;
	foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
		if ( has_term( 'us-only', 'product_cat', $cart_item['product_id'] ) ) {
			$cat_in_cart = true;
			break;
		}
	}
	if ( $cat_in_cart ) {
		wc_print_notice( 'US items are not allowed for purchase in your country. Please remove to proceed to checkout!', 'error' );
		add_action( 'woocommerce_proceed_to_checkout', 'systm_disable_checkout_button_no_shipping', 1 );
	}
}
}
?>

As you can see on line number 12 you will need to specify your ipstack API key and on line 29 the country that you wish to filter.