How to add a Discount input in Cart page on Shopify (Allow for Discount combinations)

By default, there is no discount input field on the cart page. I attempted to add a custom input form with the action set to "/discount/YOUR_CODE". However, when I try to apply two different discount codes, the second code replaces the first one. Shopify allows for discount combinations, so this experience is not ideal.

Comment (1)

Jese Leos

September 14, 2024

Verified user

After investigating, I found that we can achieve this by using the URL format "/checkout?discount=CODE1,CODE2,CODE3". Here are the steps with sample code: Add a new template named cart-discount.liquid in the snippets/ folder with the following code: <style> .cart_discounts { column-gap: 7px; display: flex; flex-wrap: wrap; justify-content: flex-end; margin-bottom: 15px; row-gap: 7px; } .cart_discounts li { background-color: #ededed; border-radius: 5px; padding: 7px 9px; } .cart_discounts span { text-transform: uppercase; } .cart_discounts .remove-discount { align-items: center; cursor: pointer; display: flex; height: 10px; justify-content: center; margin-left: 9px; opacity: 0.5; width: 10px; } .cart_discounts .remove-discount:hover { opacity: 1; transition: 0.3; } .custom-discount-form { margin-bottom: 7px; } .custom-discount-form input { flex: 1; } .custom-discount-form input:focus-visible { outline: none; } .custom-discount-form .form { display: flex; gap: 7px; } .custom-discount-form .error { color: red; display: none; } </style> <div class="cart_discounts-block" style="margin: 0 auto; max-width: 80vw"> {% assign discount_codes = "" %} {% assign discount_list = "" %} {% for discount_application in cart.cart_level_discount_applications %} {% if discount_application.type == "discount_code" %} {% assign discount_codes = discount_codes | append: ',' | append: discount_application.title %} {% endif %} {% assign discount_list = discount_list | append: ',' | append: discount_application.title %} {% endfor %} {% for item in cart.items %} {% if item.line_level_discount_allocations.size %} {% for line_discount in item.line_level_discount_allocations %} {% if line_discount.discount_application.type == "discount_code" %} {% assign discount_codes = discount_codes | append: ',' | append: line_discount.discount_application.title %} {% endif %} {% assign discount_list = discount_list | append: ',' | append: line_discount.discount_application.title %} {% endfor %} {% endif %} {% endfor %} {% assign discount_codes = discount_codes | remove_first: ',' | split: ',' | uniq | join: ',' %} {% assign discount_list = discount_list | remove_first: ',' | split: ',' | uniq | join: ',' %} <div class="custom-discount-form"> <div class="form"> <input name="custom-discount-input" type="text" /> <button class="submit-discount button">Apply</button> </div> <p class="error">Enter a valid discount code or gift card</p> </div> <ul class="cart_discounts list-unstyled" role="list" aria-label="{{ 'customer.order.discount' | t }}"> {% assign codes = discount_list | split: ',' %} {% for code in codes %} {% if discount_codes contains code %} <li class="discounts__discount discounts__discount--position"> {%- render 'icon-discount' -%} <span>{{ code | escape }}</span> <span class="remove-discount" data-code="{{ code }}"> {%- render 'icon-close' -%} </span> </li> {% else %} <li class="discounts__discount discounts__discount--position"> {%- render 'icon-discount' -%} <span>{{ code | escape }}</span> </li> {% endif %} {% endfor %} </ul> </div> <script> let enteredDiscountCode = ''; function reloadCart() { const targetUrl = '/cart.js'; fetch(targetUrl, {method: 'GET'}).then(res => { return res.json(); }).then(data => { const appliedDiscounts = []; console.log(data); data.cart_level_discount_applications.forEach((discount) => { if(discount.type === 'discount_code') { appliedDiscounts.push(discount.title); } }); data.items.forEach((item) => { item.line_level_discount_allocations.forEach((discount) => { if(discount.discount_application.type === 'discount_code') { appliedDiscounts.push(discount.discount_application.title); } }); }); console.log(appliedDiscounts); if (appliedDiscounts.indexOf(enteredDiscountCode) === -1) { const errorElement = document.querySelector('.custom-discount-form p.error'); errorElement.style.display = 'block'; errorElement.textContent = 'Enter a valid discount code or gift card'; } else { window.location.reload(); } }); } document.querySelector('.submit-discount').addEventListener('click', (e) => { const discountcodes = '{{ discount_codes }}'.split(',') ? '{{ discount_codes }}'.split(',') : []; const discountCode = document.querySelector('.custom-discount-form input').value.trim(); document.querySelector('.custom-discount-form p.error').style.display = "none"; if (discountCode && discountCode.length) { if (discountcodes.indexOf(discountCode) === -1) { discountcodes.push(discountCode); enteredDiscountCode = discountCode; const targetUrl = '/checkout?discount=' + discountcodes.join(','); fetch(targetUrl, {method: 'GET'}).finally(() => { reloadCart(); }); } else { const errorElement = document.querySelector('.custom-discount-form p.error'); errorElement.style.display = 'block'; errorElement.textContent = 'Entered Coupon was applied'; } } else { const errorElement = document.querySelector('.custom-discount-form p.error'); errorElement.style.display = 'block'; errorElement.textContent = 'Enter a valid discount code or gift card'; } }); const codeTags = document.querySelectorAll('.remove-discount'); codeTags.forEach(function(codeTag) { codeTag.addEventListener("click", function() { const discountcodes = '{{ discount_codes }}'.split(',') ? '{{ discount_codes }}'.split(',') : []; const discountCode = this.dataset.code; const remainCodes = discountcodes.filter(function(code) { return code !== discountCode }); const targetUrl = '/checkout?discount=' + remainCodes.join(','); fetch(targetUrl, {method: 'GET'}).finally(() => { window.location.reload(); }); }); }); </script> Run code snippetExpand snippet Open file sections/main-cart-footer.liquid and add {% render 'cart-discount' %} under div class="cart__blocks" And this is the result: Note: My code currently only applies for discounts of products and collections; it does not apply for discounts of shipping yet. You can try to add more logic later.

You’ll be in good company