Join us for an upcoming Shopify Partner webinar on February 27, 2024. Discover the latest Checkout Extensibility features, and deep dive on improvements to Shopify Functions and Web Pixels. Register now for either the 10am EST or 2pm EST sessions.

Bug Report: Cart Attributes are fundamentally unreliable for Function Input data

bishpls
Shopify Partner
26 6 21

Currently, the only mechanism for an app or theme to forward dynamic data about a session into a Function is via Cart Attributes. (cart.attribute: https://shopify.dev/api/functions/reference/order-discounts/graphql/common-objects/cart)

 

This is an extremely problematic single point of failure, as cart attributes are completely obliterated by Dynamic Checkout (Buy It Now) buttons, meaning Functions relying on attribute data to calculate Discount logic cannot be expected to run reliably on any merchant store including Dynamic Checkout buttons (which are enabled by default in Dawn). This effectively cripples the feature before it's even launched, as traditional workarounds for the Dynamic Checkout button problem (notably, post-Order reconciliation via Webhook and/or Order Status page ScriptTag) are not applicable to Functions.

 

See the official Help docs on Dynamic Checkout Buttons that note this incompatibility, as well as the myriad community forum issues complaining of this behavior, a handful of which I've linked below:

 

https://help.shopify.com/en/manual/online-store/dynamic-checkout/compatibility

 

https://community.shopify.com/c/shopify-apps/cart-attributes-and-dynamic-checkout-buttons/m-p/105603...

 

https://community.shopify.com/c/technical-q-a/venture-theme-set-cart-attribute-from-the-quot-buy-quo...

 

https://community.shopify.com/c/shopify-design/requiring-cart-attributes-when-using-dynamic-checkout...

 

https://community.shopify.com/c/technical-q-a/cart-attributes-not-always-saving/m-p/715733

 

https://community.shopify.com/c/shopify-design/add-input-for-cart-attribute-on-product-page/m-p/5458...

 

Replies 5 (5)

Nick_Wesselman
Shopify Staff
117 29 45

Thanks for the report! As a workaround or replacement for cart attributes, would line item attributes fit your use case? These are passed with Dynamic Checkout.

Nick Wesselman | Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit the Shopify Help Center or the Shopify Blog

bishpls
Shopify Partner
26 6 21

Does CartLine.attribute map to line_item.properties? 

https://shopify.dev/api/liquid/objects#line_item-properties  

https://shopify.dev/api/ajax/reference/cart#add-line-item-properties

 

(And if so, should that be noted / potentially renamed for consistency within the Function docs?)

 

If so -- that might be a workaround for some cases, but given that there's no clean, reliable way to listen for 'on add to cart' events within themes or theme app extensions, (outside of severe hackery involving maintaining an open socket connection to a backend processing cart/update webhook events, or theme-specific manual code modification involving wrapping / replacing add-to-cart functionality) I don't think it completely solves the problem, since apps don't necessarily have a line item to push data to. 

 

I suppose you could conceive of a workaround polling the cart AJAX API at given intervals to see if it has line items in order to push properties onto them...but at that point we're in 'workarounds on workarounds' territory, still sacrificing reliability, and using a field for something it's not at all intended for. 

 

EDIT: Actually, even then, there's never a guaranteed point at which app code even has a line item in a cart to push data to, since if the first existence of the line item is via dynamic checkout, the app may never GET an opportunity to push data. 

Dan_Bennett
Shopify Expert
3 0 0

Nick,

We are having a similar problem with line item attributes. We have custom features when added to the cart that are passed with an attribute so we know what customization the customer wants. They work fine as they show in the cart and on the checkout page. However, we have had some orders come through where the attribute isn't showing. What's odd is the same order will have some products showing the attribute and others not. Additionally, we can't recreate the error even using the same products in our test order.

 

Any thoughts on this issue?

 

Thanks

RussellMaxfield
Shopify Partner
1 0 0

I was trying to figure out why the attributes I was adding via AJAX (as specified here) It wasn't until i stumbled upon this thread that i realized it was the buy now button. This is super painful for me and seems like a big ol bug that should be addressed, as in any attribute added should persist all the way through to the order.

 

@bishpls were you able to come up with a work around in the mean time?

@Nick_Wesselman Is there an alternative to adding persisted data to the cart/order when a customer checks out using buy now?

bishpls
Shopify Partner
26 6 21

A workaround for Functions? Not that I'm aware of*.

 

A workaround for a more standard checkout / order flow capturing data? Yes, but it's not pretty. Store any attributes you absolutely must have in localStorage or a cookie, run a separate reconciliation script delivered via Order Status Page-scoped ScriptTag, and deal with merging the data into the resulting Order / your database as you see fit.

(* Technically, if disabling the dynamic checkout / Buy It Now button isn't an option, you could theoretically roll your own Buy It Now button and include the cart attributes in the query string of it; under the hood, dynamic checkout buttons basically just use cart permalinks, which allow for the submission of cart attributes to the created Checkout instance automatically as part of the URL. This is ABSOLUTELY something Shopify could resolve on their end, it would just entail a significant change to the default dynamic checkout buttons. I've lodged a few complaints about this issue already and I have a submission somewhere in the archive of the developer Discord pointing out exactly what code that could be changed to accomplish this.)