How to prevent discount stacking in tiered discount code script?

Topic summary

A Shopify store owner seeks to prevent discount code stacking with their tiered discount script. The original script automatically applies percentage discounts based on cart spend thresholds ($30/10% off, $50/15% off, $100/20% off) but allows customers to enter additional discount codes at checkout.

Solution Provided:
A contributor shares an updated script requiring a specific discount code to activate tiered pricing. The modified version supports multiple discount tiers (e.g., STANDARD_CODE and AMBASSADOR_CODE with different discount percentages). Key implementation details:

  • Create 0% discount codes in Shopify Admin
  • The script handles actual discount calculations
  • Each code can trigger different tier structures

Common Issues Raised:

  • Script applies discounts per line item rather than cart subtotal (causing $10 off each item instead of $10 off total order)
  • Questions about restricting eligible items/collections
  • Script not functioning or showing $0 discount in cart
  • Installation confusion (requires Shopify Plus and Script Editor app)

Current Status:
The thread remains open with unresolved questions about cart-level discounting and item restrictions. Note: Shopify Scripts are being deprecated in 2025 in favor of Checkout Functions and authorized apps.

Summarized with AI on November 15. AI used: claude-sonnet-4-5-20250929.

Hey!

Our store is trying to implement a tiered discount based on spend and found the below script which executes fairly well for us. The problem that we’re running into is that it allows a user to enter in a discount code at checkout that stacks upon the existing discount. I’m wondering if anyone has an example script where a single discount code is required in order to execute the below. The other alternative would be for us to disable entering in a coupon code altogether when we run a promo like this, however we would prefer to track this + allow users from other channels (e.g. ambassadors) to be able to use codes that have a higher % off:

TyTyTy for any help / tips here!

# ================================ Customizable Settings ================================
# ================================================================
# Tiered Discounts by Spend Threshold
#
# If the cart total is greater than (or equal to) an entered
# threshold, the associated discount is applied to each item.
#
#   - 'threshold' is the spend amount needed to qualify
#   - 'discount_type' is the type of discount to provide. Can be
#     either:
#       - ':percent'
#       - ':dollar'
#   - 'discount_amount' is the percentage/dollar discount to
#     apply (per item)
#   - 'discount_message' is the message to show when a discount
#     is applied
# ================================================================
SPENDING_THRESHOLDS = [
  {
    threshold: 30,
    discount_type: :percent,
    discount_amount: 10,
    discount_message: 'Spend $30 and get 10% off!',
  },
  {
    threshold: 50,
    discount_type: :percent,
    discount_amount: 15,
    discount_message: 'Spend $50 and get 15% off!',
  },
  {
    threshold: 100,
    discount_type: :percent,
    discount_amount: 20,
    discount_message: 'Spend $100 and get 20% off!',
  },
]

# ================================ Script Code (do not edit) ================================
# ================================================================
# DiscountApplicator
#
# Applies the entered discount to the supplied line item.
# ================================================================
class DiscountApplicator
  def initialize(discount_type, discount_amount, discount_message)
    _type = discount_type
    _message = discount_message

    _amount = if discount_type == :percent
      1 - (discount_amount * 0.01)
    else
      Money.new(cents: 100) * discount_amount
    end
  end

  def apply(line_item)
    new_line_price = if _type == :percent
      line_item.line_price * _amount
    else
      [line_item.line_price - (@discount_amount * line_item.quantity), Money.zero].max
    end

    line_item.change_line_price(new_line_price, message: _message)
  end
end

# ================================================================
# TieredDiscountBySpendCampaign
#
# If the cart total is greater than (or equal to) an entered
# threshold, the associated discount is applied to each item.
# ================================================================
class TieredDiscountBySpendCampaign
  def initialize(tiers)
     = tiers.sort_by { |tier| tier[:threshold] }.reverse
  end

  def run(cart)
    applicable_tier = .find { |tier| cart.subtotal_price >= (Money.new(cents: 100) * tier[:threshold]) }
    return if applicable_tier.nil?

    discount_applicator = DiscountApplicator.new(
      applicable_tier[:discount_type],
      applicable_tier[:discount_amount],
      applicable_tier[:discount_message]
    )

    cart.line_items.each do |line_item|
      next if line_item.variant.product.gift_card?
      discount_applicator.apply(line_item)
    end
  end
end

CAMPAIGNS = [
  TieredDiscountBySpendCampaign.new(SPENDING_THRESHOLDS),
]

CAMPAIGNS.each do |campaign|
  campaign.run(Input.cart)
end

Output.cart = Input.cart

Hi @Rastaclat ,

I created an app that lets you create scripts like this without having to write code . It has a “tiered discount” feature, so I borrowed some ideas from that.

Here is an updated script that should allow you to create two different discount codes and point them to different discount tiers.

# ================================ Customizable Settings ================================
# ================================================================
# Tiered Discounts by Spend Threshold
#
# If the cart total is greater than (or equal to) an entered
# threshold, the associated discount is applied to each item.
#
#   - 'threshold' is the spend amount needed to qualify
#   - 'discount_type' is the type of discount to provide. Can be
#     either:
#       - ':percent'
#       - ':dollar'
#   - 'discount_amount' is the percentage/dollar discount to
#     apply (per item)
#   - 'discount_message' is the message to show when a discount
#     is applied
# ================================================================
SPENDING_THRESHOLDS_STANDARD = [
  {
    threshold: 30,
    discount_type: :percent,
    discount_amount: 10,
    discount_message: 'Spend $30 and get 10% off!',
  },
  {
    threshold: 50,
    discount_type: :percent,
    discount_amount: 15,
    discount_message: 'Spend $50 and get 15% off!',
  },
  {
    threshold: 100,
    discount_type: :percent,
    discount_amount: 20,
    discount_message: 'Spend $100 and get 20% off!',
  },
]

SPENDING_THRESHOLDS_AMBASSADOR = [
  {
    threshold: 30,
    discount_type: :percent,
    discount_amount: 12.5,
    discount_message: 'Spend $30 and get 12.5% off!',
  },
  {
    threshold: 50,
    discount_type: :percent,
    discount_amount: 17.5,
    discount_message: 'Spend $50 and get 17.5% off!',
  },
  {
    threshold: 100,
    discount_type: :percent,
    discount_amount: 22.5,
    discount_message: 'Spend $100 and get 22.5% off!',
  },
]

DISCOUNT_CODES = {
  'STANDARD_CODE' => SPENDING_THRESHOLDS_STANDARD,
  'AMBASSADOR_CODE' => SPENDING_THRESHOLDS_AMBASSADOR
}

# ================================ Script Code (do not edit) ================================
# ================================================================
# DiscountApplicator
#
# Applies the entered discount to the supplied line item.
# ================================================================
class DiscountApplicator
  def initialize(discount_type, discount_amount, discount_message)
    @discount_type = discount_type
    @discount_message = discount_message

    @discount_amount = if discount_type == :percent
      1 - (discount_amount * 0.01)
    else
      Money.new(cents: 100) * discount_amount
    end
  end

  def apply(line_item)
    new_line_price = if @discount_type == :percent
      line_item.line_price * @discount_amount
    else
      [line_item.line_price - (@discount_amount * line_item.quantity), Money.zero].max
    end

    line_item.change_line_price(new_line_price, message: @discount_message)
  end
end

# ================================================================
# TieredDiscountBySpendCampaign
#
# If the cart total is greater than (or equal to) an entered
# threshold, the associated discount is applied to each item.
# ================================================================
class TieredDiscountBySpendCampaign
  def initialize(tiers)
    @tiers = tiers.sort_by { |tier| tier[:threshold] }.reverse
  end

  def run(cart)
    applicable_tier = @tiers.find { |tier| cart.subtotal_price >= (Money.new(cents: 100) * tier[:threshold]) }
    return if applicable_tier.nil?

    discount_applicator = DiscountApplicator.new(
      applicable_tier[:discount_type],
      applicable_tier[:discount_amount],
      applicable_tier[:discount_message]
    )

    cart.line_items.each do |line_item|
      next if line_item.variant.product.gift_card?
      discount_applicator.apply(line_item)
    end
  end
end

def discount_code_present(cart, code)
  !cart.discount_code.nil? and (cart.discount_code.code.upcase == code.upcase)
end

CAMPAIGNS = []

DISCOUNT_CODES.each do |discount_code|
  if discount_code_present(Input.cart, discount_code[0])
    CAMPAIGNS = [
      TieredDiscountBySpendCampaign.new(discount_code[1]),
    ]
  end
end

CAMPAIGNS.each do |campaign|
  campaign.run(Input.cart)
end

Output.cart = Input.cart

Here is a screen shot of it working for me:

Don’t forget to create the actual discount codes in the Shopify Admin > Discounts screen.

Hope that helps!

Matthew

1 Like

Hey Matthew,

Thank you for your help here! The below script worked amazing as far as requiring a discount code to be entered vs. automatically applying. I just have a question about having the code apply the correct % off depending on the $ threshold. If I create this coupon in the backend, I’m only able to assign one % off, as Shopify doesn’t allow me to create multiple codes with the same discount code name for each % off. Do you have a workaround for this?

Thanks again!

Sam

Hi Sam,

Those codes are for 0% off. The script takes care of the actual discounting. So you just need one code per tiered pricing scheme.

And for extra clarification, this script supports two different codes (currently STANDARD_CODE and AMBASSADOR_CODE). You can change those codes to match the ones you create in the Shopify Admin > Discounts area. Here is a screen shots of my discount codes:

However, if I wanted to change the codes, I would edit this area of the code I supplied you.

DISCOUNT_CODES = {
  'STANDARD_CODE' => SPENDING_THRESHOLDS_STANDARD,
  'AMBASSADOR_CODE' => SPENDING_THRESHOLDS_AMBASSADOR
}

Instead I might use a new code for the standard discount called “TIERED_SPECIAL”. If so, my code would look like this:

DISCOUNT_CODES = {
  'TIERED_SPECIAL' => SPENDING_THRESHOLDS_STANDARD,
  'AMBASSADOR_CODE' => SPENDING_THRESHOLDS_AMBASSADOR
}

And then I would need to add a new 0% off discount code to match:

In any case, the discount code is only used to activate the portion of the script that creates the actual tiered discounts.

Hopefully that works for you. If so, feel free to mark this as the accepted solution.

Thanks!
Matthew

2 Likes

Hey Matt,

Can you point me in the right direction on where to paste this script. I have tried the theme.liquid and the cart.liquid but no luck.

Thank you,

Jerry

Im not sure why this is happening? Did I miss something?

# ================================ Customizable Settings ================================
# ================================================================
# Tiered Discounts by Spend Threshold
#
# If the cart total is greater than (or equal to) an entered
# threshold, the associated discount is applied to each item.
#
#   - 'threshold' is the spend amount needed to qualify
#   - 'discount_type' is the type of discount to provide. Can be
#     either:
#       - ':percent'
#       - ':dollar'
#   - 'discount_amount' is the percentage/dollar discount to
#     apply (per item)
#   - 'discount_message' is the message to show when a discount
#     is applied
# ================================================================
SPENDING_THRESHOLDS_STANDARD = [
  {
    threshold: 100,
    discount_type: :dollar,
    discount_amount: 15,
    discount_message: 'Spend $100 and get $15 off!',
  },
  {
    threshold: 200,
    discount_type: :dollar,
    discount_amount: 40,
    discount_message: 'Spend $200 and get $40 off!',
  },
  {
    threshold: 400,
    discount_type: :dollar,
    discount_amount: 100,
    discount_message: 'Spend $400 and get $100 off!',
  },
]

SPENDING_THRESHOLDS_AMBASSADOR = [
  {
    threshold: 30,
    discount_type: :percent,
    discount_amount: 12.5,
    discount_message: 'Spend $30 and get 12.5% off!',
  },
  {
    threshold: 50,
    discount_type: :percent,
    discount_amount: 17.5,
    discount_message: 'Spend $50 and get 17.5% off!',
  },
  {
    threshold: 100,
    discount_type: :percent,
    discount_amount: 22.5,
    discount_message: 'Spend $100 and get 22.5% off!',
  },
]

DISCOUNT_CODES = {
  'CYBER' => SPENDING_THRESHOLDS_STANDARD,
  'AMBASSADOR_CODE' => SPENDING_THRESHOLDS_AMBASSADOR
}

# ================================ Script Code (do not edit) ================================
# ================================================================
# DiscountApplicator
#
# Applies the entered discount to the supplied line item.
# ================================================================
class DiscountApplicator
  def initialize(discount_type, discount_amount, discount_message)
    @discount_type = discount_type
    @discount_message = discount_message

    @discount_amount = if discount_type == :percent
      1 - (discount_amount * 0.01)
    else
      Money.new(cents: 100) * discount_amount
    end
  end

  def apply(line_item)
    new_line_price = if @discount_type == :percent
      line_item.line_price * @discount_amount
    else
      [line_item.line_price - (@discount_amount * line_item.quantity), Money.zero].max
    end

    line_item.change_line_price(new_line_price, message: @discount_message)
  end
end

# ================================================================
# TieredDiscountBySpendCampaign
#
# If the cart total is greater than (or equal to) an entered
# threshold, the associated discount is applied to each item.
# ================================================================
class TieredDiscountBySpendCampaign
  def initialize(tiers)
    @tiers = tiers.sort_by { |tier| tier[:threshold] }.reverse
  end

  def run(cart)
    applicable_tier = @tiers.find { |tier| cart.subtotal_price >= (Money.new(cents: 100) * tier[:threshold]) }
    return if applicable_tier.nil?

    discount_applicator = DiscountApplicator.new(
      applicable_tier[:discount_type],
      applicable_tier[:discount_amount],
      applicable_tier[:discount_message]
    )

    cart.line_items.each do |line_item|
      next if line_item.variant.product.gift_card?
      discount_applicator.apply(line_item)
    end
  end
end

def discount_code_present(cart, code)
  !cart.discount_code.nil? and (cart.discount_code.code.upcase == code.upcase)
end

CAMPAIGNS = []

DISCOUNT_CODES.each do |discount_code|
  if discount_code_present(Input.cart, discount_code[0])
    CAMPAIGNS = [
      TieredDiscountBySpendCampaign.new(discount_code[1]),
    ]
  end
end

CAMPAIGNS.each do |campaign|
  campaign.run(Input.cart)
end

Output.cart = Input.cart

I am looking for a code that works on the cart subtotal not line item price.

For example I used the code provided but if the cart reaches $75 it is giving $10 off each item in the cart instead of just $10 off the order

1 Like

We also have the same question – Is there a way to discount the cart subtotal, rather than each individual line item if the cart threshold is met? Specifically, this script doesn’t work if we wanted to take $10 off $100, as it would discount $10 for each line item. Thank you!

@CRMW @japple I know it’s not a PLUS script, but our app can apply tiered discounts on the subtotal, rather than on each line_item. Example here.
The app works alongside scripts that use discount codes, which means you can stack a tiered discount applied with our app with a discount applied via Script.

I was looking into this code and was wondering if it could be modified to restrict the eligible items? Similar to this solution https://community.shopify.com/c/shopify-scripts/script-tiered-discounts-w-collection-condition/m-p/699301, but with your code? Thanks!

Hi @playwright-mike

Hoping you can help. I am trying to use this code, but it does nothing to the cart. Any idea what is going on? I even called into tech support and they could not figure it out. They did say something about it being older, and there may be an update to the code necessary for it to work.

================================ Customizable Settings ================================

================================================================

Tiered Discounts by Spend Threshold

If the cart total is greater than (or equal to) an entered

threshold, the associated discount is applied to each item.

- ‘threshold’ is the spend amount needed to qualify

- ‘discount_type’ is the type of discount to provide. Can be

either:

- ‘:percent’

- ‘:dollar’

- ‘discount_amount’ is the percentage/dollar discount to

apply (per item)

- ‘discount_message’ is the message to show when a discount

is applied

================================================================

SPENDING_THRESHOLDS_150 = [
{
threshold: 150,
discount_type: :percent,
discount_amount: 15,
discount_message: ‘15% off!’,
},
{
threshold: 200,
discount_type: :percent,
discount_amount: 20,
discount_message: ‘20% off!’,
},
{
threshold: 250,
discount_type: :percent,
discount_amount: 25,
discount_message: ‘25% off!’,
},
]

SPENDING_THRESHOLDS_200 = [
{
threshold: 200,
discount_type: :percent,
discount_amount: 20,
discount_message: ‘20% off!’,
},
]

SPENDING_THRESHOLDS_250 = [
{
threshold: 250,
discount_type: :percent,
discount_amount: 25,
discount_message: ‘25% off!’,
},
]

DISCOUNT_CODES = {
‘CMTEST15’ => SPENDING_THRESHOLDS_150,
‘CMTEST20’ => SPENDING_THRESHOLDS_200,
‘CMTEST25’ => SPENDING_THRESHOLDS_250,

}

================================ Script Code (do not edit) ================================

================================================================

DiscountApplicator

Applies the entered discount to the supplied line item.

================================================================

class DiscountApplicator
def initialize(discount_type, discount_amount, discount_message)
@discount_type = discount_type
@discount_message = discount_message

@discount_amount = if discount_type == :percent
1 - (discount_amount * 0.01)
else
Money.new(cents: 100) * discount_amount
end
end

def apply(line_item)
new_line_price = if @discount_type == :percent
line_item.line_price * @discount_amount
else
[line_item.line_price - (@discount_amount * line_item.quantity), Money.zero].max
end

line_item.change_line_price(new_line_price, message: @discount_message)
end
end

================================================================

TieredDiscountBySpendCampaign

If the cart total is greater than (or equal to) an entered

threshold, the associated discount is applied to each item.

================================================================

class TieredDiscountBySpendCampaign
def initialize(tiers)
@tiers = tiers.sort_by { |tier| tier[:threshold] }.reverse
end

def run(cart)
applicable_tier = @tiers.find { |tier| cart.subtotal_price >= (Money.new(cents: 100) * tier[:threshold]) }
return if applicable_tier.nil?

discount_applicator = DiscountApplicator.new(
applicable_tier[:discount_type],
applicable_tier[:discount_amount],
applicable_tier[:discount_message]
)

cart.line_items.each do |line_item|
next if line_item.variant.product.gift_card?
discount_applicator.apply(line_item)
end
end
end

def discount_code_present(cart, code)
!cart.discount_code.nil? and (cart.discount_code.code.upcase == code.upcase)
end

CAMPAIGNS =

DISCOUNT_CODES.each do |discount_code|
if discount_code_present(Input.cart, discount_code[0])
CAMPAIGNS = [
TieredDiscountBySpendCampaign.new(discount_code[1]),
]
end
end

CAMPAIGNS.each do |campaign|
campaign.run(Input.cart)
end

Output.cart = Input.cart

If you also wanted to add Free Shipping using a code that applies the discount tiers, how would you adjust that script?

I’m having the same issue where the script works but it shows Discount under the subtotal as $0, which I think will confuse customers. Has anyone figured out how to fix this?

Hi Jerry - Shopify Scripts like these are added via the Script Editor app, which is exclusive to Plus clients. If you are a Plus client, and you don’t have the now ‘offline’ Script Editor app installed already, there are some ways to still get it.

Note though that scripts like these are being deprecated in 2025, as Shopify wants checkout customizations to be made using Functions, authorized Checkout Apps, etc.

Cheers.

WhiteWater Web