This is cross posted from the shopify api forum-
I have an app that relies on identifying the cart order as it is created, and then matching up that id with any order that comes in (assuming that a cart ultimately becomes an order). Per #HunkyBill's advice, this is accomplished by reading the 'cart' cookie. This does work, however it seems like a fragile way to do something that seems like it should be done with the cart object. I have two questions:
What happens if the user has cookies turned off (is there no way then to access cart id while it is still a cart.. pre-order)?
and
Is it possible to simply add the CartId as a variable to the cart object?
Every other object has its own id, which can be accessed through Liquid... EVERY one. Except for the cart object- which is the ONLY object that links directly to another object, the Order. I do fully understand that Shopify may need a cookie variable to perform some of its functionality- and I am not suggesting modifying that process in any way. However the addition of the Cart Id to the cart object would solve all of these issues (for app developers) and provide a simple way to line up cart activity with converted orders. It also would not affect any products already built using the cart cookie.
If there is a better solution/technique for identifying a cart and then later associating it with a order, I am all ears. I am a bit stunned that this critical functionality (essentially tracking conversion) is not handled in a more robust and consistent way.
If the user has cookies turned off, then you're hosed regardless. They won't be able to build a cart without the session id from the cookie.
For the cart: You're correct, on the front end the liquid cart object doesn't have the token included. It's only available through the cookie.
This is for a couple of reasons for the omission:
First, there's only ever one cart active in a view at the time, so there's no need to differentiate it while rendering a page.
Second: Within the context of the view, the token is meaningless. The user is never going need to see it.
Personally I don't buy the argument that relying on cookies for data is fragile. Indeed, the cart variable that pops up in liquid is loaded based on the session id found in the very same cookie.
That said, I can't think of a good reason for it NOT to be included in the liquid object. I'm going to file it as a low priority feature request.
Related
For our Spartacus project, we need to introduce additional Data properties in the checkout:
We have the case, that the user needs to select a delivery mode per product.
In an ideal world, upon selection, the selected delivery mode would be saved in the NGRX Store and also in the Backend to stay within the principle of the data binding defined here: https://sap.github.io/spartacus-docs/connecting-to-other-systems/#component-data-binding
Expected Data / User flow:
User goes to Checkout and to Delivery Mode Step
Custom OCC Call is made to load the supported delivery modes for each product (depends on product type and further customer specific logic)
The cart items are displayed, enhanced with a dropdown containing the available delivery modes
The user selects a delivery mode
The selected delivery mode is stored on the cart entry within the NGRX Store and saved in the backend
The new Cart totals is calculated based on the costs of the selected delivery mode
The new Cart totals is stored on the cart within the NGRX Store and saved in the backend
The user clicks on continue to get to the Review Order Step
The cart items are listed with the previously selected delivery mode
After some analysis of the existing code, we found a property deliveryMode on the orderEntry. This does not seem to be used anywhere in spartacus, but could be used to make Step 9 work by following this stackoverflow answer and this one.
Questions regarding this flow:
How can we extend the NGRX Store? We assume, it would be possible to just extend the facade (Active Cart Service), bypass the store and save the information in the backend (Described here) and afterwards refresh the store from the backend. Is that Assumption correct? If yes, that feels awkward though, as we need to reload the whole store just to contain the new property deliveryMode on the orderEntry
How can we hook into the price calculation of the cart totals to update the total based on the selected delivery mode? And again, how can we bring the new total sum into the store?
There seem to be several Answers within the Slack Channel without very few usable answers around extending the ngrx store, even though for us, it seems to be a quit normal task.. :-/
Any thoughts, inputs or support would be very appreciated. :-)
This seems like a difficult thing to accomplish seeing as delivery modes per product aren't supported as-is in spartacus. But some ideas:
You can extend core CartEntry classes (adapter, connecter, facade, etc.) to include the delivery mode for entries added to the cart. You will probably need to change all to include the delivery mode setting(s). All of these are exposed so you can modify them as needed including the store.
Utilizing multiple carts to have a product per cart and set delivery mode that way. But this would be cumbersome in my opinion.
As far as price calculation goes, I'm assuming OCC calls return total prices. Does the call for the cart entries include delivery mode costs per entry?
We have implemented the following work around and it works so far:
Enhance the Cart Model in the backend
Add new Endpoints to load the available delivery Modes per Product (by bypassing the NGRX Store)
Add new Endpoints to save the selected Delivery Mode (by bypassing the NGRX Store)
After Save Endpoint, a cart Reload is triggered, which loads the new cart totals having a custom property on the order entry (via type augmentation) into the store from the backend
It's already a lot of years past since Spartacus project started, but looks like it's still really raw projects. Spartacus is not ready to deal with real word customer's requirement and complexity of customize it quickly grow at real project(so you start to think do we really need it, as it's so unflexible at some dimentions). Some parts is really hard or not possible to customize, so you begin to search a workarounds(This question is one common case).
I think NGRX Store is one of the biggest pain in the ass to customize something at Spartacus. 2 years past and nothing changed by Spartacus team...
I have made this page https://tns.webwars.eu. This is a form that creates a skymap in away by filling the fields and then posts the data to https://the-night-sky.com/cart. I am using the cart.attributes feature at the moment but this applies for the whole cart and I want individual data for each item. Eg. If someone tries to add another map with different information.
Is there another way to pass the field values to the cart and therefore to checkout and confirmation email?
Thank you in advance
You should use Line Item Properties as described in good detail here: https://help.shopify.com/en/themes/customization/products/features/get-customization-information-for-products
That technique is per product, works perfect with the cart, checkout and admin, and is much easier to maintain than cart attributes.
You can use Shopify's Ajax API for that purpose:
https://help.shopify.com/en/themes/development/getting-started/using-ajax-api
Shopify provides shop-owners with an Ajax API that returns JSON-encoded responses.
This Ajax API makes it possible to add items to the cart, update quantities in the cart, and fetch information about the cart, without a page refresh. With this API, you can also fetch information about a particular product using its handle.
For example, on site: https://weedrepublic.com
We had a developer add a custom code to certain product pages so that the user could order multiple quantities of multiple product variants all at once from one product page.
The issue is that the script takes too long to run...when you click Add To Cart it is taking 30-60 seconds or more to add all the products to the cart.
That is way too long. (see video here https://www.dipietro.biz/wp-content/uploads/2017/04/add-to-cart-slow.webm )
This is because the script is adding each product to the cart sequentially one by one instead of simultaneously.
Is this something that can be fixed?
We need the Add To Cart speed increased drastically.
I've been told that if we had access to the cart.php file that sits on BigCommerce's server we could just add some type of ajax multi array function and that would solve the problem but of course we do not have access to BigCommerce's servers.
Any help is appreciated at this point.
Thanks!
Without seeing the code, most likely the issue is that, as you mentioned, the products are being added to the cart sequentially, while also waiting for each individual add to cart request to finish before beginning the next - that is, it will add a product to the cart, wait for that product to successfully be added, and then proceed to add the next product to the cart.
Each 'add to cart' action is an individual POST request to the cart.php file. There is a challenge here in that BigCommerce will block the requests if too many of them occur within a certain time period; this is a BigCommerce security feature.
While you do not have access to the cart.php file, and while I do not know the specifics of the BigCommerce rate-limit/security feature, the best way to approach this is to determine and set a feasible max number of concurrent requests as well as a necessary cool-down period in order to maximize the number of requests to BigCommerce while also satisfying the security/rate-limit limitation.
For example, you might set up the program to concurrently add 3 products to the cart, wait 1 second, and then proceed to add another 3 products. Does this make sense?
All I'm wanting to do is track sales of certain products from a certain date. My company is wanting to add a banner to track sales goals for raising money for charities. So basically, we'd tag a few products as being part of that goal, set a goal, and then need to update the goal progress by a certain amount every time a sale is made on one of those products. As far as I can tell, without access to Shopify's analytics API, this is not possible. How can I do this?
What you want to build is perfectly possible. However, you need to generate Private App Credentials, so you can use Shopify API. It doesn't matter if you have an account by yourself, someone else can follow these steps and send you the credentials your way.
If you don't actually need to modify anything through the API, you could have them set a webhook (Settings -> Notifications -> Webhook) on Order Creation (or similar) that posts to your server and you can check what product got sold and see if it has got the tag.
The "easy" way to do this is to create an app that receives order webhooks and can check on tagged products and keep a sum of target items sold.
Then the app should have use a script tag to insert a simple script with the current value into the web page at a configured place by css selector
OR the app could update one or more snippet files that you could include until the promo is done.
I'd tend to go with the script tag option since that's a bit more flexible and you should be able to change your theme when the promo is over to report results without having to touch the app again.
We're using the Shopify API to grab data from orders, but we're having some trouble with data validation on the fulfillment side. Is there any way we can add data validation to our checkout page? Even just Javascript validation would be a huge improvement. By the time we see an error, the customer is out of the loop, so we're having to make assumptions about our user's data which is potentially dangerous.
One example is that user typed in a phone number that began with a 1 e.g. (xxx)-1xx-xxxx, which is invalid. Another typed an address that was too long for the shipping API we send it to. We don't want to truncate arbitrary addresses so is there a way to present an error to the customer?
The checkout server is a black box as far as the API is concerned. This is mainly for security reasons.
Unfortunately, this prevents you from doing the kind of extra validation you're asking about during the checkout process.