Back to Blog

2021-06-09

shopifyguides

Free Shopify Scripts for Shopify Plus Stores

Free Shopify Scripts for Shopify Plus Stores

People are charging a lot to make these, so with the help of OnlyGrowth I worked to make a ton of these that people can copy and paste to use on their stores. This is for Shopify Plus only right now.


1. Getting started with Buy 2 Get 1 Free

PAID_ITEM_COUNT = 2
DISCOUNTED_ITEM_COUNT = 1

# 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 items that are to be discounted.
#
# Arguments
# ---------
#
# * cart
#   The cart to which split items will be 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, skip to the next item
    next if count <= 0

    if count >= line_item.quantity
      # If the full item quantity must be discounted, 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, 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? && product.id == 592406273
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 2 get 1 free")
end

Output.cart = Input.cart

2. Next we move on to Buy 1 Get 1 For $X

PAID_ITEM_COUNT = 1
DISCOUNTED_ITEM_COUNT = 1

# 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 items that are to be discounted.
#
# Arguments
# ---------
#
# * cart
#   The cart to which split items will be 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
  @percent = Decimal.new(50) / 100.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, skip to the next item
    next if count <= 0

    if count >= line_item.quantity
      # If the full item quantity must be discounted, 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, 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? && product.id == 415268529
end

discounted_line_items = partition(Input.cart, eligible_items)
discounted_line_items.each do |line_item|
  line_discount = line_item.line_price * @percent
  line_item.change_line_price(line_item.line_price - line_discount, message: "Buy one, get one 50% off")
end

Output.cart = Input.cart

3. Want to give a % discount instead? Buy 1 Get 1 For X% Off

PAID_ITEM_COUNT = 1
DISCOUNTED_ITEM_COUNT = 1

# 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 items that are to be discounted.
#
# Arguments
# ---------
#
# * cart
#   The cart to which split items will be 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
  @percent = Decimal.new(50) / 100.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, skip to the next item
    next if count <= 0

    if count >= line_item.quantity
      # If the full item quantity must be discounted, 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, 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? && product.id == 415268529
end

discounted_line_items = partition(Input.cart, eligible_items)
discounted_line_items.each do |line_item|
  line_discount = line_item.line_price * @percent
  line_item.change_line_price(line_item.line_price - line_discount, message: "Buy one, get one 50% off")
end

Output.cart = Input.cart

4. Love tiered pricing? Buy X quantity of a product, Get $Y off

DISCOUNTS_BY_QUANTITY = {
  10_000 => 20,
  1_000 => 15,
  100 => 10,
  10 => 5,
}

Input.cart.line_items.each do |line_item|
  next if line_item.variant.product.gift_card?

  quantity, discount = DISCOUNTS_BY_QUANTITY.find do |quantity, _|
    line_item.quantity >= quantity
  end
  next unless discount

  message = "$#{discount} off when buying at least #{quantity}."
  line_item.change_line_price(
    line_item.line_price - (Money.new(cents:100) * discount),
    message: message,
  )
end

Output.cart = Input.cart

5. More tiered pricing! Buy X quantity of a product, Get Y% off

DISCOUNTS_BY_QUANTITY = {
  10_000 => 20,
  1_000 => 15,
  100 => 10,
  10 => 5,
}

Input.cart.line_items.each do |line_item|
  next if line_item.variant.product.gift_card?

  quantity, discount = DISCOUNTS_BY_QUANTITY.find do |quantity, _|
    line_item.quantity >= quantity
  end
  next unless discount

  message = "#{discount}% off when buying at least #{quantity}."
  line_item.change_line_price(
    line_item.line_price * (Decimal.new(1) - discount.to_d / 100),
    message: message,
  )
end

Output.cart = Input.cart

6. Offer a discount on a certain product Tag! X% off all products with Y tag

@percent = Decimal.new(25) / 100.0
Input.cart.line_items.each do |line_item|
product = line_item.variant.product
next if product.gift_card?
next unless product.tags.include?('myTag')
line_discount = line_item.line_price * @percent
line_item.change_line_price(line_item.line_price - line_discount, message: "25% Off")
end

Output.cart = Input.cart

7. More product tag discounts! $X off all products with Y tag

Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  next if product.gift_card?
  next unless product.tags.include?('MyTag')
  line_item.change_line_price(line_item.line_price - Money.new(cents: 500), message: "$5 Off")
end

Output.cart = Input.cart

8. Spend at least $X (value in cart), Get $Y off

min_discount_order_amount = Money.new(cents:100) * 30 #minimum amount needed to have in cart to get discount
total = Input.cart.subtotal_price_was
discount = if total > min_discount_order_amount
              500 #discount amount you are offering in cents
            else
              0
            end
message = "Here's $5 off" #discount message shown to customer

Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  next if product.gift_card?
  line_item.change_line_price(line_item.line_price - Money.new(cents: discount), message: message) unless discount == 0
end

Output.cart = Input.cart

9. Spend at least $X (value in cart), Get Y% off

min_discount_order_amount = Money.new(cents:100) * 30 #number of dollars needed in cart to get the discount
total = Input.cart.subtotal_price_was
discount = if total > min_discount_order_amount
              0.2 #discount percentage in decimal form
            else
              0
            end
message = "My message"

Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  next if product.gift_card?
  line_item.change_line_price(line_item.line_price * (1-discount), message: message) unless discount == 0
end

Output.cart = Input.cart

10. Get $X off on first purchase

customer = Input.cart.customer
discount = 0
message = ""
if customer
  if customer.orders_count < 1
    discount = 1000 #discount amount in cents
    message = "New Customer - $10 off"
  end
end
puts discount
Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  next if product.gift_card?
  line_item.change_line_price(line_item.line_price - Money.new(cents: discount), message: message) unless discount == 0
end

Output.cart = Input.cart

11. Get X% off on first purchase

customer = Input.cart.customer
discount = 0
message = ""
if customer
  if customer.orders_count == 0
    discount = 0.1 #change the discount given here
    message = "Thanks for placing your first order" #change the message shown here
    
end
puts discount
Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  next if product.gift_card?
  line_item.change_line_price(line_item.line_price * (1-discount), message: message) unless discount == 0
end

Output.cart = Input.cart

12. Have purchased at least X orders, Get Y% off

customer = Input.cart.customer
discount = 0
message = ""
if customer
  if customer.orders_count > 2 #number of orders needed to get discount
    discount = 0.2 #percent discount in decimal form
    message = "VIP Customer"
  end
end
puts discount
Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  next if product.gift_card?
  line_item.change_line_price(line_item.line_price * (1-discount), message: message) unless discount == 0
end

Output.cart = Input.cart

13. Have purchased at least X orders, Get $Y off

customer = Input.cart.customer
discount = 0
message = ""
if customer
  if customer.orders_count > 2 #number of orders placed to get the deal
    discount = 1000 #discount amount in cents
    message = "VIP Customer - $10 off"
  end
end
puts discount
Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  next if product.gift_card?
  line_item.change_line_price(line_item.line_price - Money.new(cents: discount), message: message) unless discount == 0
end

Output.cart = Input.cart

14. X$ off if customer accepts marketing

customer = Input.cart.customer
discount = 0
message = ""
if customer
  if customer.accepts_marketing? #determines if the customer accepts marketing
    discount = 1000 #number of Dollars to discount in cents
    message = "Accepts Marketing Discount" #message to customer when they get the discount
  end
end
puts discount
Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  next if product.gift_card?
  line_item.change_line_price(line_item.line_price - Money.new(cents: discount), message: message) unless discount == 0
end

Output.cart = Input.cart

15. % off on W if X, Y, Z in cart

discounted_product = 1522083265
products_needed = [592406273, 4283854977, 4284984897]
products_seen = []

Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  products_seen << product.id if products_needed.include?(product.id)
end

Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  next unless product.id == discounted_product
  line_item.change_line_price(line_item.line_price * 0.90, message: "My Sale") if products_seen.uniq.sort == products_needed.uniq.sort
end

Output.cart = Input.cart

15. $ off on W if X, Y, Z in cart

discount = Money.new(cents: 100) * 5
discounted_product = 1522083265
products_needed = [592406273, 4283854977, 4284984897]
products_seen = []

Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  products_seen << product.id if products_needed.include?(product.id)
end

Input.cart.line_items.each do |line_item|
  product = line_item.variant.product
  next unless product.id == discounted_product
  line_item.change_line_price(line_item.line_price - discount, message: "My Sale") if products_seen.uniq.sort == products_needed.uniq.sort
end

Output.cart = Input.cart