[BUG?] Subscription Shipping Profile Ignored Unless Variant Explicitly in Selling Plan Group

We’ve encountered a change in how Shopify calculates delivery options (ie shipping rates) for subscriptions. Previously, if a product in a subscription contract carried a valid selling plan ID from a selling plan group that was associated with the subscription shipping profile, Shopify would return the correct subscription rate — even if the line’s variant wasn’t originally included in that specific selling plan group.

Recently, Shopify appears to have changed this behavior. Now, if the selling plan ID on the subscription line does not explicitly match one of the product’s available selling plans (at the moment of requesting delivery options), Shopify defaults to returning the general shipping profile’s rate instead of the subscription profile’s rate.

Steps to Reproduce (Case 1: Variant Swap)

  1. Create two subscription plan groups (e.g. “Legacy Plan” and “New Plan”), each with distinct variants (e.g. “Legacy Variant” and “New Variant”).

  2. Associate both plan groups with the same subscription shipping profile (give it a free rate and make sure the general profile is paid so that you can see the clear difference).

  3. Create a subscription with Legacy Variant and Legacy Plan. Now you should have a subscription contract with one line that contains the Legacy Variant and the Legacy Plan Selling Plan Id

  4. Request delivery options for the contract. Result: Subscription shipping profile rates returned. All good

  5. Swap the variant ID on the new subscription contract’s line to that of New Variant but do not update the selling plan Id of the line.

  6. Request the delivery options for the subscription.

  7. Rate returned = general shipping profile, not subscription profile’s rate.

Steps to Reproduce (Case 2: Add-ons)

  1. Create a subscription with variants tied to a subscription shipping profile. (basically - run through steps 1 through 3 above)

  2. Request delivery options for the contract. Result: Subscription shipping profile rates returned. All good

  3. Add a new line to the subscription with a variant that does not belong to any selling plan groups and use the selling plan id of the existing line (some merchants like to have variants that are only available as one-time add-ons to subscription customers so they don’t want to add them to selling plans and make them available as subscriptions on their shop).

  4. Result: the add-on product may not actually belong to that specific selling plan group.

  5. Request delivery options for the contract. Result: General shipping profile rates returned. (not good)

Expected Behavior (previous behavior)

If the selling plan ID belongs to a subscription plan group associated with a subscription shipping profile, Shopify should return the subscription profile’s rate — even if the specific product is not part of that plan group. This is the way it’s been since the creation of the subscriptions api as far as I can tell.

Actual Behavior (new behavior)

Shopify only returns the subscription shipping profile rate if the product/variant itself is associated with the selling plan’s group at the moment you request the delivery options. Otherwise, it falls back to the general shipping profile.

Impact

  • Swapping variants in a subscription causes major issues for shipping rate calculations

  • Add-ons also fall into this failure path, since the selling plan ID assigned to ensure subscription shipping is used is no longer accepted unless the product explicitly belongs to the plan.

  • Customers are being charged higher or incorrect shipping fees in cases that previously worked as intended.

Questions for Shopify

Can this behavior be reverted to the prior model, where selling plan ID + shipping profile association was sufficient for correct rate calculation?

1 Like

Hey @Brian_Singer, Thanks for the detailed bug report

Looking at your description, can you share the specific queries and mutatiuons you are using or making? For example are referencing the subscriptionDraft.deliveryOptions? The reason I ask is this query is designed to return delivery options based on the current state of the draft, which could explain the behavior you’re seeing.

Hey @KyleG-Shopify - thanks for the quick response.

I can definitely provide an example. I know this part of the API is complex and has changed over time and can be easy to trip over user error. We’re fairly confident there’s been a change though. Here’s an example:

Steps taken:

  1. checked out with “Product 1” (gid://shopify/ProductVariant/47657887629541) on “Old Plan” (gid://shopify/SellingPlan/5922160869)
  2. Shopify generated SC (subscription contract). I was able to confirm that the deliveryOptions returned were correct at this point. That plan is associated with a subscription shipping profile that is essentially “free shipping” and that product is in that plan. So Shopify returned the SubscriptionShippingOption with a $0.00 price
  3. Added a line to the subscription contract with “Product 2” (gid://shopify/ProductVariant/47657888153829) with the “Old Plan” (gid://shopify/SellingPlan/5922160869) from the first step
  4. Now I requested the delivery options again, but this time it returned the non-free “Economy” rate from the General Profile. Not from the profile associated with the plan.

I can’t say exactly when this changed but previously it was true that this would return the expected free rate. But it seems that since “Product 2” is not associated with the Selling Plan Group that “Old Plan” is part of, the shipping profile associated with “Old Plan” is no longer used.

Subscription contract: gid://shopify/SubscriptionContract/13163495653

Lines in sub:

  • gid://shopify/SubscriptionLine/0bc40ed7-2e33-41c3-9789-41adcb0f4b29
    • gid://shopify/ProductVariant/47657888153829 (“Product 2”)
  • gid://shopify/SubscriptionLine/b406f911-f5d1-43aa-960a-750369f6544c
    • gid://shopify/ProductVariant/47657887629541 (“Product 1”)

Selling Plan Id (on both lines): gid://shopify/SellingPlan/5922160869

x-request-id of the gql request to get the draft’s deliveryOptions that is returning the unexpected rate: 26e0fa86-cafb-4416-8303-ee6df6c276c7-1757502098


Now if I go through the exact same steps as above ^ but I use a selling plan group (“New Plan”) that “Product 2” is currently associated with that is also associated with the free subscription shipping profile then Shopify returns the delivery options I’m expecting above (with the free rate). But this would be a really prohibitive requirement and has implications on swaps, add-ons, etc in subscription management for customers. I’m hoping it was just an oversight in a recent change :folded_hands:

here’s an example of this ^ case

Subscription Contract: gid://shopify/SubscriptionContract/13163462885

Lines in sub:

  • gid://shopify/SubscriptionLine/3c6fbc98-a0d5-4c52-a60b-2f0984caeb03
    • gid://shopify/ProductVariant/47657887629541 (“Product 1”)
    • gid://shopify/SellingPlan/5922160869 (“Old Plan”)
  • gid://shopify/SubscriptionLine/ffa8b7d8-dc8d-41d1-aba8-5c8826b9f0cd
    • gid://shopify/ProductVariant/47657888153829 (“Product 2”)
    • gid://shopify/SellingPlan/5922226405 (“New Plan”)

x-request-id of the gql request to get the draft’s deliveryOptions that is returning the rate I’d expect both for this case and the previous ^ 575354aa-a242-45c9-ba97-f51884185fb4-1757502508

I hope this helps the dev team take a look! Thanks again


Also - in case its helpful, yes the query I’m using for the deliveryOptions is the one you called out. I’m simply creating a draft (not making any changes to the draft) and then requesting the deliveryOptions for that draft. Ex:

query subscriptionDraftShippingOptions($draftId: ID!) {
  subscriptionDraft(id: $draftId) {
    id
    deliveryOptions {
      __typename
      ... on SubscriptionDeliveryOptionResultSuccess {
        deliveryOptions {
					__typename
					... on SubscriptionShippingOption {
						title
						
						price {
							amount
							currencyCode
						}
						code
						presentmentTitle
						description
					}
        }
      }
      ... on  SubscriptionDeliveryOptionResultFailure{
        message
      }
    }
  }
}

with query vars:

{
	"draftId": "gid://shopify/SubscriptionDraft/152950833381"
}

Thanks for those details Brian. I’m taking a look here to see what I can find for you.

1 Like

Hey @Brian_Singer, we are still digging in to this here. Can you help us with a bit of a timeline on when you noticed this change?

Hey @KyleG-Shopify thanks for digging in!

Its not something that we monitor obviously but my team is confident that this was working as expected a few months ago (as we made a change specifically to ensure that we always added a selling plan in specific cases to ensure subscription shipping profiles were used). The issue was brought to our attention by our merchants about 2 or 3 weeks ago (late August); our merchants tend to find these things pretty quickly so I’m guessing it changed in August but its possible it changed anywhere in between late May and now.

I hope that helps!

Thanks Brian, I’ve passed that context on :clinking_beer_mugs:

Hey @KyleG-Shopify , any update on this? Thanks.

Hey @adrian, we are looking in to this. Are you noticing similar behaviour as Brian has reported? If you have some examples and a timeline when you noticed a change that will be helpful as well!