sellingPlan availability in order webhook

We have an emerging use case where we need to identify which products in an order are part of a subscription vs a one-time purchase.

This data seems to be available when querying the order via the graphql api at the sellingPlanconnection, but I’m not seeing that information available in the line item properties in the order webhook json, either create or update.

Without these being present in the webhook payload it means we need to make API calls and use up quota as part of what should be purely background processing.

Am I missing something here? Is there some way to get this information included in the webhook payload?

You are correct that the order webhooks (such as order/create or order/updated) do not include the full selling plan or subscription information for each line item in their payload. The selling plan details (such as whether a line item is part of a subscription or a one-time purchase) are available via the GraphQL Admin API when querying an order, specifically through the sellingPlanAllocation field on each line item. However, this information is not present in the webhook payloads by default.

Is there a way to get this information in the webhook payload?

Currently, there is no built-in way to include the full selling plan or subscription details for each line item directly in the order webhook payload. The webhook payloads are not customizable to include additional fields like sellingPlanAllocation or sellingPlanId for line items.

What can you do?

  • You must make a follow-up API call to the Admin GraphQL API to fetch the order and its line items, including the sellingPlanAllocation field, to determine which products are part of a subscription.

  • This is a known limitation and is a common pain point for apps that need to process subscription data in the background.

Example: Fetching selling plan info for order line items

You can use the order query to fetch the selling plan allocation for each line item:

query GetOrderSellingPlans {
  order(id: "gid://shopify/Order/1234567890") {
    id
    name
    lineItems(first: 50) {
      edges {
        node {
          id
          title
          quantity
          sellingPlanAllocation {
            sellingPlan {
              id
              name
            }
          }
        }
      }
    }
  }
}

That being said….adding a line item property is somehow a valid workaround, but it comes with important caveats:

  • Line item properties are arbitrary key-value pairs that can be attached to a line item at the time it is added to the cart or order.

  • These properties are included in the order webhook payload, so you can access them in your background processing without an extra API call.

  • However, line item properties are not automatically set by Shopify for subscription or selling plan information. You would need to ensure that your checkout or subscription app explicitly adds a property (e.g., "is_subscription": "true" or "selling_plan_id": "12345") when the item is added to the cart or order.

How to add a line item property

If you control the storefront or the app that adds subscription products to the cart, you can add a property like this:

items: [
  {
    quantity: 1,
    id: 794864229,
    properties: {
      '_is_subscription': 'true',
      '_selling_plan_id': '12345'
    }
  }
]

This property will then appear in the order webhook payload under the line item’s properties field.

Limitations

  • This approach only works if you can guarantee that the property is set at the time of cart or checkout creation.

  • If customers can purchase subscriptions through other means (e.g., third-party apps or channels you don’t control), those orders may not have the property set.

  • This is not a Shopify-supported or enforced method for tracking subscriptions, so it is only as reliable as your implementation. i.e if you do it on a theme level - your sales channels will not pick it up. Ideally the line item property should be added via shopify function at checkout.

Hope this helps

interesting idea, but yeah doesn’t work if we’re primarily processing order data from orders that we didn’t create/control

I take it there have been no indications or acknowledgement from shopify on this limitation?

yeah good point, line item properties is not something that would cover retroactive orders but that should not be an issue for order.create webhook. However for order.update - you can run an additional api call check if it’s subscription then update the line item property or not.

Hey @atreidesend :waving_hand: sorry this got missed and circling back on this older thread with some new info.

There’s now an update for this! Order webhook payloads include selling_plan_id on line items in API version 2026-10 and later. The field contains the selling plan ID for subscription items and is null for items that aren’t part of a subscription.

You can find the details in the Orders webhooks now include selling_plan_id on line items changelog post. Earlier API versions are unaffected, so your webhook subscription needs to use 2026-10 or later to receive the field.

Hope this helps!

Nice one, thanks for the follow up, we’ll add it to our list for when we bump to that API version.

Cheers!

Thanks again @Wes-Dev-Shopify, we’ve moved to 2026-10 and are now comparing selling_plan_id against the Admin API for every order line, and there’s one case where they disagree.

For a decent share of line items (around 11% of our order deliveries, concentrated on stores using subscription apps), the webhook gives selling_plan_id: null while the GraphQL LineItem.sellingPlan for the same line is present with a name but a null sellingPlanId.

Those look like recurring orders created through subscription contracts, where the plan is recorded by name without a Shopify selling plan behind it. The changelog says the field is null “for line items that aren’t part of a subscription”, but by the API’s own data these lines are part of one.

Is the above behavior expected or a surprise to you as well?

to be clear, it’s mostly seen on orders with source name of subscription_contract_checkout_one but we have also seen it on a handful of orders with source name of web as well (across more than one site)

Thanks for the extra detail @atreidesend.

The GraphQL schema (https://shopify.dev/docs/api/admin-graphql/2026-10/objects/LineItemSellingPlan) allows sellingPlanId to be null even when a plan name is present, so I’m checking the expected behaviour for these subscription orders and whether the changelog wording needs clarification.

I’ve sent you a DM with a request for a couple of affected orders, including a web example. I’ll follow up here once I have more information.