skip to Main Content

I try to get a shipping ID list by country like flat_rate:1, local_pickup:2 etc.
I tried this below

$all_zones = WC_Shipping_Zones::get_zones();
$country_code = 'BE';
foreach ($all_zones as $zone) {
    foreach ($zone['zone_locations'] as $location) {
        if ($country_code === $location->code) {
            foreach ($zone['shipping_methods'] as $flat_rate) {
                print_r($flat_rate);//ID here
            }
        }
    }
}

I tried also this but I can not set a country by myself?

$shippingmethods = WC()->session->get( 'shipping_for_package_0')['rates'];
foreach ($shippingmethods as $shippingmethod ) {
    shippingmethod->get_id();
}

2

Answers


  1. The following will give you the shipping rate Id that you are looking for… It works for all defined shipping zones and also Rest of the World shipping zone (when no country matches).

    The code:

    // $country_code      = WC()->customer->get_shipping_country();
    $country_code      = 'BE';
    $defined_zones     = WC_Shipping_Zones::get_zones();
    $shipping_rate_ids = array(); // Initializing
    $country_found     = false;
    
    // Loop through defined shipping zones
    foreach ($defined_zones as $zone) {
        foreach ($zone['zone_locations'] as $location ) {
            if ( 'country' === $location->type && $country_code === $location->code ) {
                foreach ($zone['shipping_methods'] as $shipping_method ) {
                    $method_id   = $shipping_method->id;
                    $instance_id = $shipping_method->instance_id;
                    $rate_id     = $method_id . ':' . $instance_id;
    
                    $shipping_rate_ids[$instance_id] = $rate_id;
                }
                $country_found = true;
                break; // Country found stop "locations" loop
            }
        }
    }
    
    // Rest of the word (shipping zone)
    if( ! $country_found ) {
        $zone = new WC_Shipping_Zone(0); // Rest of the word (zone)
    
        foreach ( $zone->get_shipping_methods( true, 'values' ) as $shipping_method ) {
            $method_id   = $shipping_method->id;
            $instance_id = $shipping_method->instance_id;
            $rate_id     = $method_id . ':' . $instance_id;
    
            $shipping_rate_ids[$instance_id] = $rate_id;
        }
    }
    
    // testing raw output
    echo '<pre>' . print_r( $shipping_rate_ids, true ) . '</pre>';
    

    Tested and work.

    Login or Signup to reply.
  2. Changed this line $method_id = $shipping_method->method_id; to $shipping_method->id;

    This fixed the issue Notice: Undefined property: WC_Shipping_Flat_Rate::$method_id

    // $country_code      = WC()->customer->get_shipping_country();
        $country_code      = 'NL';
        $defined_zones     = WC_Shipping_Zones::get_zones();
        $shipping_rate_ids = array(); // Initializing
        $country_found     = false;
    
        // Loop through defined shipping zones
        foreach ($defined_zones as $zone) {
            foreach ($zone['zone_locations'] as $location ) {
                if ( 'country' === $location->type && $country_code === $location->code ) {
                    foreach ($zone['shipping_methods'] as $shipping_method ) {
                        $method_id   = $shipping_method->id;
                        $instance_id = $shipping_method->instance_id;
                        $rate_id     = $method_id . ':' . $instance_id;
                        $shipping_rate_ids[$instance_id] = $rate_id;
                    }
                    $country_found = true;
                    break; // Country found stop "locations" loop
                }
            }
        }
    
    // Rest of the word (shipping zone)
    if( ! $country_found ) {
        $zone = new WC_Shipping_Zone(0); // Rest of the word (zone)
    
        foreach ( $zone->get_shipping_methods( true, 'values' ) as $shipping_method ) {
            $method_id   = $shipping_method->id;
            $instance_id = $shipping_method->instance_id;
            $rate_id     = $method_id . ':' . $instance_id;
    
            $shipping_rate_ids[$instance_id] = $rate_id;
        }
    }
    
    echo '<pre>' . print_r( $shipping_rate_ids, true ) . '</pre>';
    

    Tested and work

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search