Personalized checkout and custom promotions with Shopify Scripts
Hi -
I'm trying to figure out how to write a Shopify Script that uses a discount code for tiered discounting to prevent people using codes on top of the automatic discounts AND that excludes sale items. An important note, is we need it to work if Sale items are in the cart, just not apply an additional discount to those items. When I use shopify's line item code to disable discounts, it doesn't let you use a discount if any of those items are even in the cart. That is not what we are trying to do.
For example:
Code: Holidays
Tiers Based On Cart Subtotal: 10% off 100, 20% off 200, 30% off 300
Does Not Work On Sale Items or Does Not Work On Tag: Sale
I got this far...
# ================================ 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: :percent,
discount_amount: 10,
discount_message: 'Spend $100 and get 10% off!',
},
{
threshold: 200,
discount_type: :percent,
discount_amount: 20,
discount_message: 'Spend $200 and get 20% off!',
},
{
threshold: 300,
discount_type: :percent,
discount_amount: 30,
discount_message: 'Spend $300 and get 30% off!',
},
]
SPENDING_THRESHOLDS_AMBASSADOR = [
{
threshold: 150,
discount_type: :percent,
discount_amount: 22,
discount_message: 'Spend $150 and get 22% off!',
},
{
threshold: 250,
discount_type: :percent,
discount_amount: 33,
discount_message: 'Spend $350 and get 33% off!',
},
{
threshold: 350,
discount_type: :percent,
discount_amount: 44,
discount_message: 'Spend $350 and get 44% off!',
},
]
DISCOUNT_CODES = {
'OHMYGOURD' => SPENDING_THRESHOLDS_STANDARD,
'BFVIP' => 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|
puts line_item.variant.product.tags
next if line_item.variant.product.gift_card? or line_item.variant.product.tags.include?'sale'
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
Starting a B2B store is a big undertaking that requires careful planning and execution. W...
By JasonH Sep 23, 2024By investing 30 minutes of your time, you can unlock the potential for increased sales,...
By Jacqui Sep 11, 2024We appreciate the diverse ways you participate in and engage with the Shopify Communi...
By JasonH Sep 9, 2024