Example scripts
Scripts are flexible and can be used to create unique and powerful discounts. For example, you can create scripts that change the prices and properties of line items in your online store's cart based on the items that a customer adds to it.
You can find examples of common scripts in the script templates that are provided in the Script Editor. To view these examples, you need to create a script.
Here are some other script examples:
Percentage off all items
This line item script multiplies the price of each line item in the cart by 0.9, resulting in a 10% discount.
Input.cart.line_items.each do |item|
item.change_line_price(item.line_price * 0.9, message: "10% off all items!")
end
Output.cart = Input.cart
Percentage off all shipping rates
This shipping script discounts all shipping rates by 0.10, resulting in a 10% discount on shipping.
Input.shipping_rates.each do |shipping_rate|
next unless shipping_rate.source == "shopify"
shipping_rate.apply_discount(shipping_rate.price * 0.10, message: "Discounted shipping")
end
Output.shipping_rates = Input.shipping_rates
Remove a shipping rate
This shipping script hides shipping options that start with the string EXPRESS.
Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
shipping_rate.name.upcase.start_with?("EXPRESS")
end
Rename a payment provider
The following script renames the Cash on Delivery (COD) payment provider to a custom name.
Input.payment_gateways.each do |payment_gateway|
next unless payment_gateway.name == "Cash on Delivery (COD)"
payment_gateway.change_name("Custom Name")
end
Output.payment_gateways = Input.payment_gateways
Stop customers from using a discount code
You can use a line item script to temporarily stop customers from applying a discount code at checkout. For example, during a Black Friday Cyber Monday sale, the following script tells your customers that their discount code can't be used:
if Input.cart.discount_code
Input.cart.discount_code.reject(
message: "Maximum discount already applied! Discount codes can not be used during this promotion."
)
end
Output.cart = Input.cart
If you have a Shopify Plus plan, you can remove the Discount code field from your checkout. To remove this field, add the following code to your checkout.liquid file.
<style>
[data-reduction-form="update"] {
display: none
}
</style>
Ruby
# Use an array to keep track of the discount campaigns desired.
CAMPAIGNS = [
# $5 off all items with the "sale" tag
ItemCampaign.new(
AndSelector.new(
TagSelector.new("sale"),
ExcludeGiftCardSelector.new,
),
MoneyDiscount.new(5_00, "5$ off all items on sale",),
),
# 10% off all items with a price lower than $100
ItemCampaign.new(
AndSelector.new(
ExcludeGiftCardSelector.new,
PriceSelector.new(:lower_than, Money.new(cents: 100_00)),
),
PercentageDiscount.new(10, "10% off all items under 100$"),
),
# Give every 3rd item with the tag "letter" for free
BogoCampaign.new(
TagSelector.new("letter"),
PercentageDiscount.new(100, "Third item is free"),
LowToHighPartitioner.new(2,1),
)
]
# Iterate through each of the discount campaigns.
CAMPAIGNS.each do |campaign|
# Apply the campaign onto the cart.
campaign.run(Input.cart)
end
# To have the changes to the line items be reflected, the output of
# the script needs to be specified.
Output.cart = Input.cart
Buy one, get one free
This script gives one product for free if the customer purchases at least one of those products.
# Buy One, Get One Free Script
# The basis of this script is provided by the Script Editor itself as a "default" script option.
# Adjusting these values lets you tweak the scope of the discount, eg:
# PAID_ITEM_COUNT = 1, DISCOUNTED_ITEM_COUNT = 1 -> Buy One, Get One
# PAID_ITEM_COUNT = 3, DISCOUNTED_ITEM_COUNT = 2 -> Buy Three, Get Two
PAID_ITEM_COUNT = 1
DISCOUNTED_ITEM_COUNT = 1
# Specify the IDs of the products you want to be eligible for this promotion.
ELIGIBLE_PRODUCT_IDS = [9307791812, 9307791940]
# Returns the integer amount of items that must be discounted next
# given the amount of items seen
#
def discounted_items_to_find(total_items_seen, discounted_items_seen)
Integer(total_items_seen / (PAID_ITEM_COUNT + DISCOUNTED_ITEM_COUNT) * DISCOUNTED_ITEM_COUNT) - discounted_items_seen
end
# Partitions the items and returns the discounted items.
#
# Arguments
# ---------
#
# * cart
# The cart to which split items are added (typically Input.cart).
#
# * line_items
# The selected items that are applicable for the campaign.
#
def partition(cart, line_items)
# Sort the items by price from high to low
sorted_items = line_items.sort_by{|line_item| line_item.variant.price}.reverse
# Create an array of items to return
discounted_items = []
# Keep counters of items seen and discounted, to avoid having to recalculate on each iteration
total_items_seen = 0
discounted_items_seen = 0
# Loop over all the items and find those to be discounted
sorted_items.each do |line_item|
total_items_seen += line_item.quantity
# After incrementing total_items_seen, see if any items must be discounted
count = discounted_items_to_find(total_items_seen, discounted_items_seen)
# If there are none, then skip to the next item
next if count <= 0
if count >= line_item.quantity
# If the full item quantity must be discounted, then add it to the items to return
# and increment the count of discounted items
discounted_items.push(line_item)
discounted_items_seen += line_item.quantity
else
# If only part of the item must be discounted, then split the item
discounted_item = line_item.split(take: count)
# Insert the newly-created item in the cart, right after the original item
position = cart.line_items.find_index(line_item)
cart.line_items.insert(position + 1, discounted_item)
# Add it to the list of items to return
discounted_items.push(discounted_item)
discounted_items_seen += discounted_item.quantity
end
end
# Return the items to be discounted
discounted_items
end
eligible_items = Input.cart.line_items.select do |line_item|
product = line_item.variant.product
!product.gift_card? && ELIGIBLE_PRODUCT_IDS.include?(product.id)
end
discounted_line_items = partition(Input.cart, eligible_items)
discounted_line_items.each do |line_item|
line_item.change_line_price(Money.zero, message: "Buy one, get one free!")
end
Output.cart = Input.cart
New customer discount
This script gives a percentage discount for new customers.
DISCOUNT_AMOUNT = 20
if Input.cart.line_items.size > 1 && (Input.cart.customer.nil? || Input.cart.customer.orders_count < 1)
line_item = Input.cart.line_items.sort_by { |line_item| line_item.variant.price }.first
if line_item.quantity > 1
line_item = line_item.split(take: 1)
Input.cart.line_items << line_item
end
line_item.change_line_price(line_item.line_price * (1.0 - (DISCOUNT_AMOUNT / 100.0)), message: "#{DISCOUNT_AMOUNT}% off for first-time customers!")
end
Output.cart = Input.cart
Percentage off least expensive items
This script takes a percentage off the least expensive item in a cart.
DISCOUNT_AMOUNT = 15
if (Input.cart.line_items.size > 1)
line_item = Input.cart.line_items.sort_by { |line_item| line_item.variant.price }.first
if line_item.quantity > 1
line_item = line_item.split(take: 1)
Input.cart.line_items << line_item
end
line_item.change_line_price(line_item.line_price * (1.0 - (DISCOUNT_AMOUNT / 100.0)), message: "#{DISCOUNT_AMOUNT}% off!")
end
Output.cart = Input.cart
Tiered pricing for bulk purchases
This script can offer a higher percentage discount on a product as a customer adds more to their cart. For example, a customer receives a 5% discount for a cart with 1 to 5 products, a 10% discount on a cart with 6 to 10 products, and so on.
# Define a list of price tiers.
PRICE_TIERS = [
# Pricing tiers for Shoes
{
product_types: ['Shoes'],
group_by: :product, # :product or :variant
tiers: [
{
quantity: 10,
discount_percentage: 10,
discount_message: '10% off for 10+'
},
{
quantity: 50,
discount_percentage: 15,
discount_message: '15% off for 50+'
}
]
}
]
# In most cases, you don't need to edit below this line.
##
# Tiered pricing campaign.
class TieredPricingCampaign
def initialize(partitioner, tiers)
@partitioner = partitioner
@tiers = tiers.sort_by { |tier| tier[:quantity] }
end
def run(cart)
@partitioner.partition(cart).each do |k, items|
total_quantity = items.map(&:quantity).reduce(0, :+)
applicable_tier = find_tier_for_quantity(total_quantity)
unless applicable_tier.nil?
apply_tier_discount(items, applicable_tier)
end
end
end
private
def find_tier_for_quantity(quantity)
@tiers.select { |tier| tier[:quantity] <= quantity }.last
end
def apply_tier_discount(items, tier)
discount = get_tier_discount(tier)
items.each do |item|
discount.apply(item)
end
end
def get_tier_discount(tier)
PercentageDiscount.new(tier[:discount_percentage], tier[:discount_message])
end
end
##
# Select line items by product type.
class ProductTypeSelector
def initialize(product_types)
@product_types = Array(product_types).map(&:upcase)
end
def match?(line_item)
@product_types.include?(line_item.variant.product.product_type.upcase)
end
def group_key
@product_types.join(',')
end
end
##
# Apply a percentage discount to a line item.
class PercentageDiscount
def initialize(percent, message = '')
@percent = Decimal.new(percent) / 100.0
@message = message
end
def apply(item)
line_discount = item.original_line_price * @percent
new_line_price = item.original_line_price - line_discount
if new_line_price < item.line_price
item.change_line_price(new_line_price, message: @message)
end
end
end
##
# A pricing tier partition.
class TierPartitioner
def initialize(selector, group_by)
@selector = selector
@group_by = group_by
end
def partition(cart)
# Filter items
items = cart.line_items.select { |item| @selector.match?(item) }
# Group items using the appropriate key.
cart.line_items.group_by { |item| group_key(item) }
end
private
def group_key(line_item)
case @group_by
when :product
line_item.variant.product.id
when :variant
line_item.variant.id
else
@selector.group_key
end
end
end
##
# Instantiate and run Price Tiers.
PRICE_TIERS.each do |pt|
TieredPricingCampaign.new(
TierPartitioner.new(
ProductTypeSelector.new(pt[:product_types]),
pt[:group_by]
),
pt[:tiers]
).run(Input.cart)
end
##
# Export changes.
Output.cart = Input.cart
Tiered discounts by spending threshold
This script offers increasing discounts based on the increased total value of the cart. For example, a customer receives a 5% discount on an order over $50, a 10% discount on an order over $100, and so on.
# Define spending thresholds, from lowest spend to highest cart value.
SPENDING_THRESHOLDS = [
{
spend: 3000, # spend amount (in cents)
discount: 10 # percentage discount
},
{
spend: 5000,
discount: 15
},
{
spend: 10000,
discount: 20
}
]
# Find any applicable spending threshold.
eligible_threshold = nil
SPENDING_THRESHOLDS.each do |threshold|
if Input.cart.subtotal_price_was.cents >= threshold[:spend]
eligible_threshold = threshold
end
end
# Apply threshold.
if !eligible_threshold.nil?
Input.cart.line_items.each do |line_item|
line_item.change_line_price(line_item.line_price * (1.0 - (eligible_threshold[:discount] / 100.0)), message: "#{eligible_threshold[:discount]}% off for purchases over $#{eligible_threshold[:spend] / 100}!")
end
end
Output.cart = Input.cart
Free gift with purchase
This script offers a free gift with a purchase. You can define how many products need to be included in a purchase for a customer to receive the free gift.
# Define the ID of the free product.
FREE_GIFT_PRODUCT_ID = 9307791812
# Check that we have at least two items in the cart (so that there's a "purchase").
if Input.cart.line_items.size > 1
Input.cart.line_items.each do |line_item|
# If the free gift is found, set its price to zero.
if line_item.variant.product.id == FREE_GIFT_PRODUCT_ID
if line_item.quantity > 1
line_item = line_item.split(take: 1)
Input.cart.line_items << line_item
end
line_item.change_line_price(Money.zero, message: "Free gift with purchase!")
end
end
end
# Export the cart.
Output.cart = Input.cart
Free standard shipping for a specific customer group
This script offers free shipping to a specified customer group. For example, you can use tag certain customers with VIP
and then offer free shipping to those customers..
# Define a list of shipping service names that are eligible for free shipping for VIPs.
ELIGIBLE_SERVICES = ['Standard Ground Shipping']
# Define the tag that identifies VIP customers.
VIP_CUSTOMER_TAG = 'VIP'
# If the customer is a VIP, give them free shipping on the defined services.
if !Input.cart.customer.nil? and Input.cart.customer.tags.include?(VIP_CUSTOMER_TAG)
Input.shipping_rates.each do |shipping_rate|
if ELIGIBLE_SERVICES.include?(shipping_rate.name)
shipping_rate.apply_discount(shipping_rate.price, message: "Free shipping for VIP customers!")
end
end
end
# Export the rates.
Output.shipping_rates = Input.shipping_rates
Pick up in store if a customer is close to particular location
This script lets customers pick up their order in store if their postal code prefix matches the list set in this script.
# Define the name of the pick up shipping rate - this should be added manually in the Shopify Admin.
PICKUP_SHIPPING_RATE_NAME = 'Pick Up In-Store'
# Define a list of postcode prefixes that are allowed to pick up from the store.
PICKUP_POSTCODE_PREFIXES = [
'100', '101', '102'
]
# Output filtered shipping rates.
Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
(shipping_rate.name == PICKUP_SHIPPING_RATE_NAME) && !PICKUP_POSTCODE_PREFIXES.any? { |prefix| Input.cart.shipping_address.zip.start_with?(prefix) }
end
Percentage off next order if customer accepts marketing
This script gives a customer a percentage off their next order if they have accepted marketing when they placed their first order.
# Define the discount for eligible customers.
DISCOUNT_AMOUNT = 10
# Checks to see if this is a customer's second order, and that they opted into marketing when they placed their first order.
if (!Input.cart.customer.nil? && Input.cart.customer.orders_count == 1 && Input.cart.customer.accepts_marketing?)
Input.cart.line_items.each do |line_item|
line_item.change_line_price(line_item.line_price * (1.0 - (DISCOUNT_AMOUNT / 100.0)), message: "#{DISCOUNT_AMOUNT}% off for subscribing to our newsletter!")
end
end
Output.cart = Input.cart
Auto-select default payment methods
This script auto selects a specified payment method at the checkout.
# Define the preferred order of gateways.
PREFERRED_GATEWAY_ORDER = ['Invoice', 'Shopify Payments']
# Sort gateways.
Output.payment_gateways = Input.payment_gateways.sort_by do |payment_gateway|
PREFERRED_GATEWAY_ORDER.index(payment_gateway.name) || 999
end
Other examples
Other script examples:
Learn more
Learn more about: