Search code examples
wordpresswoocommercegeolocationproducthook-woocommerce

Make product unpurchasable based on user geolocated country and product ID in WooCommerce


I have a snippet which I have put in functions.php, what I am trying to achieve is firstly get the users location (I have Geolocate set in WooCommerce settings and MaxMind configured).

If the country code for the user is "GB" (United Kingdom) and the product they are browsing is e.g. 6104 then I then want the product to be non-puchaseable but still accessible so they can see the product info. Picture and price, etc... jsut the add-to-cart button becomes hidden.

Why is my function not working as expected? Where am I wrong and how can I adjust this feature to support multiple product IDs?

function get_user_geo_country(){
    $geo      = new WC_Geolocation(); // Get WC_Geolocation instance object
    $user_ip  = $geo->get_ip_address(); // Get user IP
    $user_geo = $geo->geolocate_ip( $user_ip ); // Get geolocated user data.
    $country  = $user_geo['country']; // Get the country code

    if ( $country === "GB" ) {
        add_filter('woocommerce_is_purchasable', 'woocommerce_cloudways_purchasable');
        function woocommerce_cloudways_purchasable($cloudways_purchasable, $product) {
            return ($product->id == 6104 ? false : $cloudways_purchasable);
        }
    }
}
add_action('wp','get_user_geo_country');

My current WooCommerce version is 6.7.0 and WordPress version 6.0.1


Solution

  • For multiple product id's you can use in_array(). Furthermore, it is not necessary to use the wp hook but can do it directly via the woocommerce_is_purchasable hook

    So you get:

    // Is purchasable
    function filter_woocommerce_is_purchasable( $purchasable, $product ) {
        // Array with product IDs
        $product_ids = array( 30, 6104, 6242, 6243 );
    
        // Get current product ID
        $product_id = $product->get_id();
    
        // Only for specific products
        if ( in_array( $product_id, $product_ids ) ) {
            // Get an instance of the WC_Geolocation object class
            $geolocation_instance = new WC_Geolocation();
    
            // Get user IP
            $user_ip_address = $geolocation_instance->get_ip_address();
    
            // Get geolocated user IP country code
            $user_geolocation = $geolocation_instance->geolocate_ip( $user_ip_address );
    
            // For specific countries
            if ( in_array( $user_geolocation['country'], array( 'GB' ) ) ) {
                // NOT purchasable
                $purchasable = false;
            }
        }
    
        return $purchasable;
    }
    add_filter( 'woocommerce_is_purchasable', 'filter_woocommerce_is_purchasable', 10, 2 );