• I have enabled two rates as a test. I enabled UPS ground and UPS second day air. When the rates are given to the customer UPS second day air is on top of the list which is the most expensive. Is there a way to sort by price?

Viewing 4 replies - 1 through 4 (of 4 total)
  • Plugin Support IQComputing Alex

    (@iqcalex)

    @djmart177 While we do have a feature within the Integration Settings page to return only the lowest shipping rate – we do not currently have any sorting feature for returned rates.

    That being said, we certainly see the benefit of a feature such as this and will look into how we can build this into a future release. We will keep this thread open and reply to it if/when this feature has been included so if you’re interested, please ensure to subscribe to topic replies here.

    In the meantime, if you’re development savvy, WooCommerce does have a PHP filter hook in which you could modify the returned package rates woocommerce_package_rates

    https://woocommerce.github.io/code-reference/files/woocommerce-includes-class-wc-shipping.html#source-view.387

    Thread Starter djmart177

    (@djmart177)

    Great idea, you put me on the right path and I had AI do the rest…

    This seems to work as a snippet to sort them.

    /**
    * Sorts WooCommerce shipping rates by cost in ASCENDING order (lowest first)
    * while preserving the unique rate IDs (keys).
    *
    * @param array $rates Array of shipping rates.
    * @return array Sorted array of shipping rates.
    */
    function custom_sort_shipping_rates_by_cost_correctly( $rates ) {
    if ( ! is_array( $rates ) || empty( $rates ) ) {
    return $rates;
    }

    // IMPORTANT: Use uasort() to sort by cost while preserving the array keys (the Rate IDs).
    uasort( $rates, function( $a, $b ) {
    // Sort in ASCENDING order (lowest cost first).
    if ( $a->cost == $b->cost ) {
    return 0;
    }
    return ( $a->cost < $b->cost ) ? -1 : 1;
    } );

    // If you want the highest cost at the BOTTOM (which is what ascending order does),
    // you are done. The lowest price will be at the top.

    return $rates;
    }
    add_filter( 'woocommerce_package_rates', 'custom_sort_shipping_rates_by_cost_correctly', 999 );

    Also, do you have any way to allow for products for free shipping? This plugin has a ton of potential but very limited in features at the moment.

    • This reply was modified 6 months, 3 weeks ago by djmart177.
    • This reply was modified 6 months, 3 weeks ago by djmart177.
    • This reply was modified 6 months, 3 weeks ago by djmart177.
    Plugin Support IQComputing Alex

    (@iqcalex)

    @djmart177 Glad to hear you were able to sort it! That snippet looks correct on the surface.

    Also, do you have any way to allow for products for free shipping?

    In regards to Products with Free Shipping, Shipping Classes seem like the way to go, but as it stands currently, WooCommerce calculates shipping as a whole order. We’re open to hearing any ideas, but it seems like we would need to build in some kind of selectbox to exclude certain Shipping Classes from getting rates. This is something we’ll add to our future feature list but we’ll need to investigate this a bit further.

    This plugin has a ton of potential but very limited in features at the moment.

    Thanks – this plugin is still in it’s infancy but will continue to grow thanks to the feedback and direction from users such as yourself. Have a wonderful rest of your week!

    Thread Starter djmart177

    (@djmart177)

    This seems to work as well. I even had it change the returned options to just show “Free Shipping” and no price attached. If the customer adds a product that is outside of the specific shipping class slug, it will then calculate shipping. Not my work, it is AI, so if you plan to use this as a guide, grain of salt.. lol

    /**
    * Custom function to check for the "Free Shipping" class, adjust rates to zero,
    * and replace the label with "Free Shipping" for all returned options.
    *
    * @param array $rates Array of shipping rates.
    * @param array $package Package of cart items.
    * @return array Modified array of shipping rates.
    */
    function custom_apply_free_shipping_by_class( $rates, $package ) {
    $has_free_shipping_class = false;
    // NOTE: Ensure this slug matches the slug of your WooCommerce shipping class exactly.
    $free_shipping_class_slug = 'free-shipping-usa-only';

    // 1. CHECK CART CONTENTS FOR THE SPECIFIC SHIPPING CLASS
    foreach ( $package['contents'] as $item ) {
    // Get the product's assigned shipping class ID
    $shipping_class_id = $item['data']->get_shipping_class_id();

    // Check if the shipping class slug matches
    if ( $shipping_class_id ) {
    $shipping_class = get_term( $shipping_class_id, 'product_shipping_class' );
    if ( $shipping_class && $shipping_class->slug === $free_shipping_class_slug ) {
    $has_free_shipping_class = true;
    break; // Found it, no need to check other items
    }
    }
    }

    // 2. ADJUST RATES AND LABELS IF THE CLASS IS FOUND
    if ( $has_free_shipping_class ) {
    $new_rates = array();

    // Loop through all calculated rates (FedEx, UPS, etc.)
    foreach ( $rates as $rate_id => $rate ) {
    /** @var \WC_Shipping_Rate $rate */

    // Clone the rate object to safely modify it
    $new_rate = clone $rate;

    // 🎯 CORE CHANGE: Set the cost to zero and replace the label
    $new_rate->cost = 0;
    $new_rate->label = 'Free Shipping';

    // Set the taxes to zero (if taxes are enabled)
    if ( ! empty( $new_rate->taxes ) ) {
    $new_rate->taxes = array_map( 'wc_format_decimal', array_fill( 0, count( $new_rate->taxes ), 0 ) );
    }

    $new_rates[ $rate_id ] = $new_rate;
    }
    $rates = $new_rates;
    }

    // 3. SORT THE FINAL RATES (Maintaining the highest-cost-at-bottom rule)
    if ( ! is_array( $rates ) || empty( $rates ) ) {
    return $rates;
    }

    // Use uasort() to sort by cost while preserving the associative keys (Rate IDs).
    uasort( $rates, function( $a, $b ) {
    // Sort in ASCENDING order (lowest cost first / highest cost at the bottom).
    if ( $a->cost == $b->cost ) {
    return 0; // Maintain order if costs are equal
    }
    return ( $a->cost < $b->cost ) ? -1 : 1;
    } );

    return $rates;
    }
    add_filter( 'woocommerce_package_rates', 'custom_apply_free_shipping_by_class', 100, 2 );
Viewing 4 replies - 1 through 4 (of 4 total)

The topic ‘Rate ordering?’ is closed to new replies.