Search code examples
phpwordpresswoocommercecheckoutshipping-method

Disable "Place order" button for specific shipping zone in WooCommerce


I am trying to deactivate the "Place order" button if a specific shipping class is selected. Name of the shipping class is "Zone 6".

Based on "Remove Woocommerce "place order" button for a specific shipping class" answer thread, I have make some changes to handle shipping zones instead:

add_filter('woocommerce_order_button_html', 'remove_order_button_html' );
function remove_order_button_html( $button ) {
    // HERE define your targeted shipping zone
    $targeted_shipping_zone = "Zone 6";
    $found = false;

    // Loop through cart items
    foreach( WC_Shipping_Zones::get_zones() as $shipping_zone ) {
        if( $shipping_zone['data']->get_zone_name() == $targeted_shipping_zone ) {
            $found = true; // The targeted shipping class is found
            break; // We stop the loop
        }
    }

    // If found we remove the button
    if( $found ) {
        $style = 'style="background:Silver !important; color:white !important; cursor: not-allowed !important;"';
        $button_text = apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) );
        $button = '<a class="button" '.$style.'>' . $button_text . '</a>';
    }
    return $button;
}

But it does not work. When setting $found to true manually the button is deactivated as wanted. I think there is a mistake in the get_zone() lines.

Any help is appreciated.


Solution

  • In your code, you are not getting the selected shipping zone, you are just looping through each existing shipping zone, so you are always getting the last one. That's why it doesn't work.

    In the following you will get the correct chosen shipping zone name:

    add_filter('woocommerce_order_button_html', 'disable_place_order_button_html' );
    function disable_place_order_button_html( $button ) {
        // HERE define your targeted shipping zone
        $targeted_zone_name = "Zone 6";
    
        // Get the chosen shipping method (if it exist)
        $chosen_shipping_methods = WC()->session->get( 'chosen_shipping_methods' );
        $chosen_shipping_method  = reset($chosen_shipping_methods);
        $chosen_shipping_method  = explode(':', $chosen_shipping_method );
        $chosen_shipping_zone    = WC_Shipping_Zones::get_zone_by( 'instance_id', end($chosen_shipping_method) );
    
        // If the targeted shipping zone is found, disable the button
        if( $targeted_zone_name == $chosen_shipping_zone->get_zone_name() ) {
            $style  = 'style="background:Silver !important; color:white !important; cursor: not-allowed !important; text-align:center;"';
            $text   = apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) );
            $button = '<a class="button" '.$style.'>' . $text . '</a>';
        }
        return $button;
    }
    

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