[Delivery Customization Function] The system does not automatically select the cheapest option by default when the shipping methods are reordered


Follow this requirement.

By default, the first shipping method is selected when the list of shipping methods is displayed. However, if the shipping methods are reordered by shipping delivery function, the system does not automatically update the selection to reflect the cheapest option. This may result in a higher-cost option remaining selected by default.

Hi @Chi_n_Nguy_n_Van :waving_hand: - generally, we display the least expensive shipping rate by default at checkout:

Could you let us know where you’re seeing this behaviour pop up? Is this in a output from a Function run or within an Extension UI? Happy to dig into this further to see if we can confirm expected behaviour.

Hope to hear from you soon!

Thank you for your response Alan_G.

As mentioned above, this behavior occurs when merchants use the Delivery Customization function to reorder their shipping options.

You can take a look at my record: https://youtu.be/jjvXRXy1FKw

In my record, when a buyer navigates to the checkout page, the first shipping option is automatically selected, which is why this behavior appears.

Thanks @Chi_n_Nguy_n_Van , that does definitely look odd, appreciate you sending that my way. Would you be open to sharing your extension code with me? We’d just need the basics in order to replicate what you’re seeing (so you can remove any non-essential code if needed there).

If you’d prefer to share that info with me via a private message, that’s cool too. I can set that up on my end if needed and reach out to you that way.

Hope to hear from you soon!

All matters should be clear based on the image provided. I am only using the payment customization function to reorder the shipping options from:

  1. Free shipping
  2. Shipping option 1
  3. Shipping option 2
  4. Shipping option 3

to:

  1. Shipping option 2
  2. Shipping option 3
  3. Shipping option 1
  4. Free shipping

As previously mentioned, Shopify selects the first shipping option by default. Therefore, in this case, the most expensive option (Shipping option 2) is automatically selected (instead of the Free shipping option)

I would simply like to confirm whether you or your team can improve this behavior—specifically, to ensure that the cheapest shipping option is selected by default after all delivery customization functions have been applied, or if there are any other recommendations or solutions.

Thanks for clarifying @Chi_n_Nguy_n_Van , just wanted to see if I could replicate the behaviour exactly. I’ll look into this for you on my end and share next steps once I have more info. Speak with you again as soon as I can.

1 Like

Hi @Chi_n_Nguy_n_Van - just following up with some info here after confirming some things with the team. At the moment, the function doesn’t override the default selection behaviour, essentially, it just renames, sorts, or hides options depending on what you set.

The default behaviour is that if a buyer hasn’t yet made a selection, the selected option will be the cheapest of the options returned after your customisation has ran. However, if the buyer has made a selection, we’ll attempt to retain that selection after the customisation has ran, so I wonder if that’s potentially happening here. If not, let me know and I’d be happy to keep digging into this (if you’re able to share any repro code that would be super helpful as well if we need to investigate further) .

Hope this helps :slight_smile:

For my record, I accessed the checkout page for the first time using an incognito window, ensuring no previous session or local storage interference. However, I noticed that the first shipping option was automatically selected, instead of the cheapest shipping option, which I expected.

This unexpected behavior is the reason I’m reporting the issue to you and your team.

And here is my delivery customization function code:

function run() {
  return {
    operations: [
      {
        move: {
          deliveryOptionHandle:
            "65888ee8b6c7c5fe045f9b2e0e57eaf1-c3e090203786bc2e8bb3ca305acd7816",
          index: 1,
        },
      },
      {
        move: {
          deliveryOptionHandle:
            "65888ee8b6c7c5fe045f9b2e0e57eaf1-6058796404e38ca1cabdcb4ec7f9ef8e",
          index: 2,
        },
      },
      {
        move: {
          deliveryOptionHandle:
            "65888ee8b6c7c5fe045f9b2e0e57eaf1-0032a34caa898da7178d58bd34dfa31c",
          index: 3,
        },
      },
    ],
  };
}

with function input:

{
  "cart": {
    "attribute": null,
    "cost": {
      "subtotalAmount": {
        "amount": "700.0",
        "currencyCode": "VND"
      }
    },
    "deliveryGroups": [
      {
        "deliveryAddress": {
          "city": "",
          "countryCode": "VN",
          "provinceCode": null,
          "zip": null
        },
        "deliveryOptions": [
          {
            "handle": "65888ee8b6c7c5fe045f9b2e0e57eaf1-80ec4a7496a2dd1c91ac653b79c996f6",
            "title": "Free shipping",
            "cost": {
              "amount": "0.0"
            }
          },
          {
            "handle": "65888ee8b6c7c5fe045f9b2e0e57eaf1-0032a34caa898da7178d58bd34dfa31c",
            "title": "Shipping option 1",
            "cost": {
              "amount": "10.0"
            }
          },
          {
            "handle": "65888ee8b6c7c5fe045f9b2e0e57eaf1-c3e090203786bc2e8bb3ca305acd7816",
            "title": "Shipping option 2",
            "cost": {
              "amount": "12.0"
            }
          },
          {
            "handle": "65888ee8b6c7c5fe045f9b2e0e57eaf1-6058796404e38ca1cabdcb4ec7f9ef8e",
            "title": "Shipping option 3",
            "cost": {
              "amount": "20.0"
            }
          }
        ]
      }
    ]
  }
}

Thanks @Chi_n_Nguy_n_Van , I’ll see if I can replicate this with your Function implementation there. I really appreciate you sending this our way.

1 Like

Thank you for taking the time to review and follow up with me. If you need anything further, please don’t hesitate to let me know.

Hey @Chi_n_Nguy_n_Van :waving_hand: - thanks for your patience. I believe I was able to replicate the behaviour you’re seeing here on my test shop with a text extension. I’ll do some further investigation into this on my end to confirm if this is expected behaviour and loop back with you once I have more info to share though. Speak with you as soon as I have that info on my end :slight_smile:

1 Like

Hey @Chi_n_Nguy_n_Van :wave:

Thanks for your patience while I looked into this, wanted to reach out to share a confirmed answer here.

I can confirm that what you’re seeing is actually the expected behaviour. When a delivery customization function reorders shipping rates, whatever rate ends up in position 0 (the first position) becomes the default selected rate, regardless of its price.

Here’s how the flow works: Shopify initially sorts rates by price with the cheapest option first. Then your delivery customization function runs and can reorder those rates using move operations. Whatever rate ends up in position 0 after your function runs becomes the default selection. The important part here is that no re-sorting happens after the function runs.

So in your example, if you’re reordering from Free shipping at the top to having Shipping option 2 at the top, Shipping option 2 will be selected by default even though it’s more expensive. This is working as designed.

I definitely realize this isn’t ideal, but hopefully this clarifies the behaviour you’re seeing. Let me know if you have any other questions about this. More than happy to help out further.

1 Like

Hi @Alan_G

Just wanted some clarification as to why app requirement #20 exists (apps cannot reorder shipping options that increases the default shipping price).

Some merchants offer options such as ‘ship using my own account’ where they bill shipping to the customer’s UPS/Fedex account directly and thus do not need to collect shipping whilst checking out, or deferred options such as ‘consolidate my orders and ship later’ where they again may offer a free option, but these options are certainly not the preferred option for most of their customers, as such there is a need for merchants to ensure a rate other than the cheapest is selected as default otherwise it causes a massive headache when customers do not read the shipping rate that is selected as default carefully and ends up checking out with the incorrect option (this happens a lot, especially with shopify shipping hiding the other options by default too).

This is a feature many merchants have asked for, with our Free app Shipping Rate Power Toy, we have thousands of merchants who use the re-ordering feature for this very purpose, preventing them from doing so is causing significant headaches for a lot of merchants.

Hey @Min_Liu :waving_hand: - thanks for raising this, and totally get where you’re coming from here.

That requirement, from our side, essentially means apps can’t reorder shipping rates in a way that causes a higher-priced shipping rate to become the default, if that makes sense.

The main reason for that requirement is to avoid buyers being defaulted into a more expensive shipping option without explicitly choosing it themselves.

That said, I definitely get the use case you’re describing here. Flows like “ship using my own account” or “consolidate and ship later” can absolutely be valid merchant-preferred options, even if they aren’t the cheapest, and I can see why having the wrong option selected by default would create headaches.

If these merchant workflows are being surfaced as standard shipping rates, then I can definitely see how that creates friction with the current requirement. I’m happy to pass this along as feedback though, since the use case you described makes sense and it’s helpful context around why merchants want more control here.

Hope that helps clarify things a bit. Please feel free to ping me here with some more details on your use case — I can’t guarantee anything, but I’m happy to advocate on my end here.

1 Like