For those of you on the Shopify Plus plan, you have the option to use the Shopify Script Editor to perform custom programming with the Ruby language. Scripts you write can modify line items, payment methods, and shipping options during checkout. While the Script Editor is being deprecated on August 25, 2025, in favor of Shopify Functions, it remains a valuable tool for enhancing the checkout experience if you already have it installed.
Recently, I needed to create a custom shipping option for work. The requirement was to offer a flat rate for the first item, with a fixed amount added for each additional item. If any item exceeded a certain weight, the promotional shipping would not apply. After defining these rules, I proceeded to code the solution using the API reference.
Since Ruby isn’t a language I use frequently, I had to look up various aspects like array handling and string manipulation functions. Although these tasks were manageable, I encountered some limitations set by Shopify. For instance, you can only offer discounts and cannot exceed a carrier-calculated rate. Additionally, you cannot inject a new option; you can only edit an existing one by renaming it or lowering its value. This meant I had to make compromises, such as editing a ground shipping option and ensuring that if the promo rate was higher than the carrier rate, the carrier rate would prevail.
While I can’t share the exact script I wrote for work, below is a similar version that follows the same rules. It should be useful until the Script Editor is phased out.
Please note, you can only have one type of script active at a time. I had to merge my existing shipping script with the new one to meet this requirement.
# Vars we need
standard_quantity = 0
overweight_quantity = 0
overweight_value = 4535.92
has_ground_option = false
has_home_option = false
use_code = ""
new_rate = 0.00
# Sum up all the line item quantities
Input.cart.line_items.each do |line_item|
if line_item.grams < overweight_value
standard_quantity += line_item.quantity
else
overweight_quantity += line_item.quantity
end
end
# View output for debugging
puts "standard_quantity => " + standard_quantity.to_s
puts "overweight_quantity => " + overweight_quantity.to_s
# Search for ground and home delivery
Input.shipping_rates.each do |shipping_rate|
if shipping_rate.code == "FEDEX_GROUND"
has_ground_option = true
end
if shipping_rate.code == "GROUND_HOME_DELIVERY"
has_home_option = true
end
end
# View output for debugging
puts "has_ground_option => " + has_ground_option.to_s
puts "has_home_option => " + has_home_option.to_s
# Which code will we use and remove
use_code = has_ground_option ? "FEDEX_GROUND" : "GROUND_HOME_DELIVERY"
# View output for debugging
puts "use_code => " + use_code.to_s
# Sometimes both ground and home delivery are returned for the same address. Shopify bug?
# Remove the one we won't be using for the promotion modification
Input.shipping_rates.delete_if do |sr|
sr.code == ((use_code == "FEDEX_GROUND") ?
"GROUND_HOME_DELIVERY" : "FEDEX_GROUND")
end
# Iterate through shipping rates
Input.shipping_rates.each do |shipping_rate|
if shipping_rate.code == use_code
if overweight_quantity == 0
# Note: values are in cents
# Base rate is $5.00, each additional is $1.00
new_rate = 500 + ((standard_quantity - 1) * 100)
# View output for debugging
puts "new_rate => " + new_rate.to_s
puts "shipping_rate.price.cents => " + shipping_rate.price.cents.to_s
# Only make the change if the promo rate is below carrier-calculated
if new_rate < shipping_rate.price.cents.to_s.to_i
shipping_rate.change_name("Shipping Promotion")
shipping_rate.change_price(Money.new(cents: new_rate), message: "discounted price")
end
end
end
end
# Sort by price in ascending order
Output.shipping_rates = Input.shipping_rates.sort_by(&:price)
Leave a Reply