Update script to give free shipping based on customer tag and shipping address country

Topic summary

A user is seeking help modifying a Shopify Ruby script that currently provides free shipping based on customer tags (VIP levels and subscribers). They want to add a restriction so the free shipping only applies to customers in Australia.

Current functionality:

  • Level 2 VIPs get free standard shipping
  • Level 3 VIPs get free express and standard shipping
  • Subscribers receive shipping discounts

Technical challenge: The existing script lacks country-based filtering logic.

Community responses:

  • One commenter suggests contacting the original script developer, as Ruby expertise is needed
  • Another confirms this requires a Ruby developer if using Shopify Plus Script Editor
  • A third recommends using the “Advanced Free Shipping” app instead, noting it uses Shopify’s newer shipping discount API and can handle customer tags + country restrictions without custom code

Key context: Shopify is deprecating Scripts in the near future, making app-based solutions potentially more sustainable than modifying legacy Ruby scripts.

The discussion remains open with no code solution provided yet.

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

We currently have a script that runs to offer free shipping based on different customer tags, but we also want to restrict this to customers in Australia.

Our current script is as below and we’re struggling to add in country parameters:

LVL2 = “swell_vip_level 2”
LVL3 = “swell_vip_level 3”
SUB = “tier: Subscriber”
MSG2 = “Free Standard Shipping”
MSG3 = “Free Express Shipping”
TYPE = “SAMPLE”
STD = “STANDARD”
EXP = “EXPRESS”
SMP = “SAMPLES”

customer = Input.cart.customer

if customer
if customer.tags.include?(LVL2)
Input.shipping_rates.each do |shipping_rate|
if shipping_rate.name.include?(“Standard”)
shipping_rate.change_name(“Free Standard Shipping”, { message: “Free Standard Shipping” })
shipping_rate.apply_discount(shipping_rate.price, message: MSG2)
end
end
end
if customer.tags.include?(LVL3)
Input.shipping_rates.each do |shipping_rate|
if shipping_rate.name.include?(“Express”)
shipping_rate.change_name(“Free Express Shipping”, { message: “Free Express Shipping” })
shipping_rate.apply_discount(shipping_rate.price, message: MSG3)
end
end
end
if customer.tags.include?(LVL3)
Input.shipping_rates.each do |shipping_rate|
if shipping_rate.name.include?(“Standard”)
shipping_rate.change_name(“Free Standard Shipping”, { message: “Free Standard Shipping” })
shipping_rate.apply_discount(shipping_rate.price, message: MSG2)
end
end
end
if customer.tags.include?(SUB)
Input.shipping_rates.each do |shipping_rate|
if shipping_rate.name.include?(“Express”)
shipping_rate.change_name(“Free Express Shipping”, { message: “Free Express Shipping” })
shipping_rate.apply_discount(shipping_rate.price, message: MSG3)
end
end
end
end

Output.shipping_rates = Input.shipping_rates.delete_if do |shipping_rate|
if Input.cart.line_items.all? { |li| li.variant.product.product_type.upcase.include?(TYPE) }
shipping_rate.name.upcase.start_with?(STD) || shipping_rate.name.upcase.start_with?(EXP)
else
shipping_rate.name.upcase.start_with?(SMP)
end
end

# ================================ Customizable Settings ================================
# ================================================================
# Discount Rate(s) by Discount Code(s)
#
# If one of the entered discount codes is used, the entered
# rate(s) are discounted by the entered amount.
#
# - ‘discount_code_match_type’ determines whether the below
# strings should be an exact or partial match. Can be:
# - ‘:exact’ for an exact match
# - ‘:partial’ for a partial match
# - ‘discount_codes’ is a list of strings to identify discount
# codes
# - ‘rate_match_type’ determines whether the below strings
# should be an exact or partial match. Can be:
# - ‘:exact’ for an exact match
# - ‘:partial’ for a partial match
# - ‘rate_names’ is a list of strings to identify rates
# - ‘discount_type’ is the type of discount to provide. Can be
# either:
# - ‘:percent’
# - ‘:dollar’
# - ‘discount_amount’ is the percentage/dollar discount to
# apply
# - ‘discount_message’ is the message to show when a discount
# is applied
# ================================================================
DISCOUNTS_FOR_DISCOUNT_CODES = [
{
discount_code_match_type: :exact,
discount_codes: [“VITAMINA-TRIAL”, “ADN-TRIAL”, “BLEMISH-TRIAL”],
rate_match_type: :exact,
rate_names: [“Standard”, “Shipping Rate”, “Other Shipping Rate”],
discount_type: :percent,
discount_amount: 100,
discount_message: “Free Shipping with discount code”
},
]

# ================================ Script Code (do not edit) ================================
# ================================================================
# DiscountCodeSelector
#
# Finds whether the supplied discount code matches any of the
# entered codes.
# ================================================================
class DiscountCodeSelector
def initialize(match_type, discount_codes)
@comparator = match_type == :exact ? ‘==’ : ‘include?’

  • @discount _codes = discount_codes.map { |discount_code| discount_code.upcase.strip }*
    end

def match?(discount_code)

  • @discount _codes.any? { |code| discount_code.code.upcase.send(@comparator, code) }*
    end
    end

# ================================================================
# RateNameSelector
#
# Finds whether the supplied rate name matches any of the entered
# names.
# ================================================================
class RateNameSelector
def initialize(match_type, rate_names)
@comparator = match_type == :exact ? ‘==’ : ‘include?’
@rate_names = rate_names.map { |rate_name| rate_name.downcase.strip }
end

def match?(shipping_rate)
@rate_names.any? { |name| shipping_rate.name.downcase.send(@comparator, name) }
end
end

# ================================================================
# DiscountApplicator
#
# Applies the entered discount to the supplied shipping rate.
# ================================================================
class DiscountApplicator
def initialize(discount_type, discount_amount, discount_message)

  • @discount _type = discount_type*

  • @discount _message = discount_message*

  • @discount _amount = if discount_type == :percent*
    discount_amount * 0.01
    else
    Money.new(cents: 100) * discount_amount
    end
    end

def apply(shipping_rate)
rate_discount = if @discount _type == :percent
shipping_rate.price * @discount _amount
else

shipping_rate.apply_discount(rate_discount, message: @discount _message)
end
end

# ================================================================
# DiscountRatesForDiscountCodeCampaign
#
# If one of the entered discount codes is used, the entered
# rate(s) are discounted by the entered amount.
# ================================================================
class DiscountRatesForDiscountCodeCampaign
def initialize(campaigns)
@campaigns = campaigns
end

def run(cart, shipping_rates)
return if cart.discount_code.nil?

@campaigns.each do |campaign|
discount_code_selector = DiscountCodeSelector.new(campaign[:discount_code_match_type], campaign[:discount_codes])

next unless discount_code_selector.match?(cart.discount_code)

rate_name_selector = RateNameSelector.new(campaign[:rate_match_type], campaign[:rate_names])
discount_applicator = DiscountApplicator.new(
campaign[:discount_type],
campaign[:discount_amount],
campaign[:discount_message],
)

shipping_rates.each do |shipping_rate|
next unless rate_name_selector.match?(shipping_rate)
discount_applicator.apply(shipping_rate)
end
end
end
end

CAMPAIGNS = [
DiscountRatesForDiscountCodeCampaign.new(DISCOUNTS_FOR_DISCOUNT_CODES),
]

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

Output.shipping_rates = Input.shipping_rates

1 Like

This looks like Ruby code, you might want to contact whoever wrote this as they have more knowledge of this ruby code than anyone else here in the community. But if you are up for it, you can contact me for help.

1 Like

If you are Shopify Plus client and using script editor you will need a ruby developer to help you with that, feel free to connect

@lana-mukti
You can easily create free shipping based on different customer tags + country using Advanced Free Shipping.
The app uses Shopify’s new shipping discount API, and lets you create shipping discounts with many different scenarios and checkout choices.
Also, with Shopify deprecating ‘Scripts’ in the near future, this is the ideal (and easy) solution.
Let me know if I can help further!