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();
}
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.