Search code examples
phpwordpresswoocommercecartcountry

Avoid checkout for specific products on specific country in Woocommerce


Here's what I want to do:
If customer selects Canada as shipping country and there's a specific product in cart, checkout should not happen and an error message should generate informing customer of why checkout didn't happen.

My research:
Add or remove woocommerce error messages has code to generate WooCommerce error messages. I asked a question yesterday that gave me codes to check if certain product is in cart and if shipping country is set to Canada Remove Canada from country list when specific products are in cart on Woocommerce I am not sure which filter/action I must hook my code to so it runs whenever "Place Order" is clicked on checkout page.

Update: So I tried combining the two codes I have listed in my research but it didn't work. Any help if I need to approach this differently will be really appreciated
Product IDs are 15631 & 12616


Solution

  • This can be done using the action hook woocommerce_check_cart_items through this custom function:

    add_action( 'woocommerce_check_cart_items', 'products_not_shipable_in_canada' );
    function products_not_shipable_in_canada() {
        // Only on checkout page (allowing customer to change the country in cart shipping calculator)
        if( ! is_checkout() ) return;
    
        // Set your products
        $products = array(15631, 12616);
    
        // Get customer country
        $country = WC()->session->get('customer')['shipping_country'];
        if( empty($country) ){
            $country = WC()->session->get('customer')['billing_country'];
        }
        // For CANADA
        if( $country == 'CA' ){
            // Loop through cart items
            foreach( WC()->cart->get_cart() as $item ){
                // IF product is in cart
                if( in_array( $item['product_id'], $products ) ){
                    // Avoid checkout and display an error notice
                    wc_add_notice( sprintf( 
                        __("The product %s can't be shipped to Canada, sorry.", "woocommerce" ),  
                        '"' . $item['data']->get_name() . '"'
                    ), 'error' );
                    break; // Stop the loop
                }
            }
        }
    }
    

    Code goes in function.php file of your active child theme (or active theme). Tested and works.

    enter image description here

    Related: Set minimum allowed weight for a specific country in WooCommerce