We are seeing regular web orders placed by customers coming with "shopify_draft_order" in the order.checkout.source_name field:
1. order.source_name = "web" 2. order.checkout.source_name = "shopify_draft_order"
Our app relies on the ability to identify legitimate web orders and to distinguish them from draft orders. We use the checkout.source_name field as we have found it to be more reliable than the order.source_name field (it likes to return "web" for legitimate draft orders). We are seeing this inconsistently for large chunks of orders on some shops are an unable to explain how this could come about.
Does anyone have any additional insight on this?
I'm also seeing similar issues with the `order.source_name` property on the `orders/create` webhook.
In addition, there's this odd quirk where an integer is passed. It's briefly mentioned in the API docs, but this really should be fixed. There's no a good reason to break the enum pattern of the list of common sense options (`web`, `pos`, `ios`, `android`).
Reading the documentation closer, apps can only modify an order's `source_name` on creation:
From the Order resource documentation:
Where the order originated. Can be set only during order creation, and is not writeable afterwards. Values for Shopify channels are protected and cannot be assigned by other API clients: web, pos, shopify_draft_order, iphone, and android. Orders created via the API can be assigned any other string of your choice. If unspecified, then new orders are assigned the value of your app's ID.
This means APPs are creating their own dynamic and non-deterministic source_name's.
In my opinion, there should be a separate attribute for channel which could include unmodifiable enum:
That way other apps that rely on orders/create webhooks can accurately determine the CHANNEL of the order's origination.
Shopify Partner Platform product team, please consider this API change!
Regarding the original issue, can you kindly provide example order_ids where the source contained unexpected values?
Also want to point out I was able to replicate this by creating a draft order, sending an email invoice, and completing the checkout from the invoice. In this case, the invoice link redirects to the web checkout for the customer to complete the purchase. The resulting order returns
web for the order.source_name, and
shopify_draft_order for the checkout.source_name. By contrast, a draft order paid directly in the admin will return a source_name of
shopify_draft_order for both the order and the checkout.
I'm not sure if this is expected as there may be use cases where you'd want to be able to differentiate orders paid through web checkout vs drafts paid directly in the admin, but I'll raise this with our teams to clarify. Please provide some examples and I'll include those as well.
The issue the design of the `order.source_name` is non-deterministic.
What I mean by that is any app that creates orders can set the `order.source_name` to whatever string they would like. In addition, if they neglect to set this value then the app's own integer based ID is set into the `order.source_name`.
@Ginko and I have separate apps that rely on the order_source being values we can anticipate ahead of time. Allowing apps to change this value to whatever they'd like makes it very difficult for us to extend functionality.
For example, in my app I allow my merchants to only send ID checks if the order was created via web, andriod, iphone and/or in store (source_name == pos). However, due to the current API design I have to compensate for an unknown number of other values.
I have a list of over 4k examples from my database alone of where `order.status_name` is not web, ios, andriod, shopify_draft_order or pos. Is there an email I should send that to? I would rather not share customer data publicly.
Makes sense, and thank you for the feedback. I'd just like to clarify that since the behaviour you described is expected, I'll be submitting that as feedback to our product teams. The teams consider partner feedback when making changes to our APIs, and any changes they decide on would be included in a future API release. Just want to mention this as the original post seemed to be reporting a bug, and the timelines are much different for feature changes vs bug reports.
Regarding the specific behaviour around the source_name appearing as
web when an order is created through a draft, I'll be sending that up to our developers as a bug report to clarify whether that behaviour is expected. If it's determined to be a bug, we'll aim to get a fix out ASAP. If you have any examples from production where an order created through a draft displays
web as the source_name, please provide the order_id and I'll include it in the report.
Hi @_JB ,
When an order is created through a draft, we initially expected the order.source_name to be shopify_draft_order but in most cases, it turned out to be web. As I understand your response, this means the customer received the invoice and did the web checkout. This is good because it allows us to identify orders where the customer never visited checkout. However, we are also trying to identify legitimate draft orders and have been using checkout.source_name to try this. From your explanation, it should work - since checkout.source_name = "shopify_draft_order" when the customer clicks an invoice and pays. However, in practice, we are seeing the "shopify_draft_order" string on the checkout for orders placed via pre-order and subscription apps too. Please see the following example:
order.id: 3745151778975 order.source_name: "web" order.checkout.source_name: "shopify_draft_order"
This order was generated by the app "Pre-order manager" (https://apps.shopify.com/pre-order) and was placed (and paid for) via the regular Shopify web checkout. In this case, we are expecting both order and checkout source_names to be web or anything other than "shopify_draft_order", but they are not - so our app is incorrectly identifying this order as a draft order.
As it stands now, it is impossible to tell which orders are actually created by merchants under draft orders.