Within an order in my store some items are Heavy and some are light. I want my packers to pack items heaviest to light so that the light items are not squashed at the bottom.

I thought I could add a custom product attribute to each item then perhaps order the items in the order by that attribute but I can't seem to do it.

I do not want to effect the main store item order, just the confirmed orders ready for delivery.

Can anyone confirm if this is possible?


  • ok So after reading your question I have got one question. Do you want to change the order [Heavy to light ] in the admin panel, or do you have any other custom page for packers Jul 13 at 7:22
  • @RajneeshTiwari Just change the order in the admin panel so the packing team pack items in the correct order (heavy to light). Thanks for the reply. Jul 13 at 8:02
  • nice. glad to hear that. Jul 17 at 4:45
  • you want to it for an order only using weight attribute which is already in woocommerce? Jul 17 at 11:30

Using a clean wordpress install, woocommerce and storefront theme, I came up with this code.

It sorts regular products and variable products only. Only sorts in admin panel. Sorts by weight from hgih to low (you can see the commented section, you can uncomment the relevant option to you).

The code goes into functions.php

add_filter('woocommerce_order_get_items', 'bt_sort_woo_order_by_weight', 10, 3);
function bt_sort_woo_order_by_weight ($items, $_this, $types) {
    if (!is_admin()) return $items;
    if (isset($types[0]) && $types[0] !== 'line_item') return $items;

    $items_sorted_by_weight = [];

    foreach ($items as $item_id => $item) {
        // get variation or product id, starting with variation
        $id = !empty($item->get_variation_id()) ? $item->get_variation_id() : $item->get_product_id();

        // get product
        $product = wc_get_product($id);

        // in case the product/variation no longer exist OR product is not variable or simple
        if (empty($product) || !in_array($product->get_type(), ['variation', 'simple'])) {
            $items_sorted_by_weight[] = [
                'weight' => 0,
                'item'   => $item


        $items_sorted_by_weight[] = [
            'weight' => floatval($product->get_weight()),
            'item'   => $item

    // sort by weight
    usort($items_sorted_by_weight, function($a, $b) {
        //return $a['weight'] <=> $b['weight']; // low to high
        return $b['weight'] <=> $a['weight']; // high to low

    // set each sorted element to contain only the item, nothing else
    foreach ($items_sorted_by_weight as &$item) {
        $item = $item['item'];

    // in case nothing worked set the sorted variable to contain default items
    if (empty($items_sorted_by_weight)) $items_sorted_by_weight = $items;

    return $items_sorted_by_weight;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.