Edit product price/apply discount code in the cart when certain rules are met

2 0 0

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:


  1. 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.

  2. 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:


    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));
            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 }}'));
    function changeItem() {
      setTimeout(() => {
        if (counts['Pastas'] >= 3) {
          fetch('/cart/change.js', {
            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);

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.

Reply 1 (1)

Shopify Partner
892 23 172

You cannot edit product price with cart ajax nor apply discount code in the cart. Discounts can only be applied at checkout. Cart ajax only allows you to add items to the cart, change the quantity, etc. 

BYOB - Build Your Own Bundles, SPO - SEO App to research keywords & edit social link preview