Dedicated to the Hydrogen framework, headless commerce, and building custom storefronts using the Storefront API.
Hi all,
I have some pretty specific rules that Shopify's discounts functionality doesn't cover so I've resorted to trying to build this myself.
I've explored both the AJAX API and Storefront API which I believe the later will probably be the solution.
My custom ruleset is essentially, if you add 3x of any product from the same collection, you can get them for £X, the 4th and 5th would be charged at the normal price but once you add the 6th the promotion will activate again.
Here's what I've tried so far:
I can get the contents of a cart and see what collection every item is in meaning I can sort them into key/value pairs like { Pastas: 3, Breadsticks: 2 } for instance and perhaps amend prices based on the quantity in the cart. But this is where I've found out that the cart/change endpoint is largely read-only so changing prices from there is impossible and I suppose it does kind of make sense since you could just go ahead and make items free. It's also unauthenticated.
I then tried to see if I could do something similar but on the checkout page but using an approach where I can obtain the items in the cart but this time, depending on the number of items in one collection (ie 3) I could expose a pre-made discount code. But alas this template isn't even in the theme. And it turns out you can only add scripts to that checkout page if you're a Plus member: https://community.shopify.com/c/shopify-apis-and-sdks/any-way-to-add-javascript-to-checkout-page/m-p...
Here's a really simple snippet of trying to use the AJAX API and realising it's read-only:
<script> var allItemsInCart = []; var counts = {}; function getCart(callback){ fetch('/cart.js', callback) .then(res => res.json() .then(parsedJson => { parsedJson.items.map(item => allItemsInCart.push(item.product_type)); console.log(allItemsInCart); allItemsInCart.forEach(function (x) { counts[x] = (counts[x] || 0) + 1; }); })) .catch(err => console.log(err)); } function updateTotalPriceOnTheScreen(cart){ //This example assumes that there's a DOM element on the page that has the ID cart-total-price console.log(Shopify.formatMoney(cart.total_price, '${{ amount }}')); } getCart(updateTotalPriceOnTheScreen); function changeItem() { setTimeout(() => { console.log(counts['Pastas']); if (counts['Pastas'] >= 3) { fetch('/cart/change.js', { method:'post', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'id': "42097702502612", 'total_discount': '33', 'price': "166" }) }) .then(res => res.json() .then(parsedJson => { console.log (parsedJson); })) .catch(err => console.log(err)); } }, 500); } changeItem(); </script>
I've set up a private app (next.js/node.js) which I'm now exploring the possibility of using GraphQL to perhaps mutate or even expose a discount code on the cart in question? But I'm not entirely sure on how the app knows what cart ID I'm referring to.
Any help would be greatly appreciated.