How to create custom discount logic on Shopify Plus
Shopify Plus allows store owners the ability to add custom server-side functionality to Line Items, Shipping, and Payments via their Script Editor app. Today I am going to share a method that allows for custom functionality around discounting using just links and the Script Editor.
This article does serve as a little teaser as to what can be achieved via custom line properties within the Script Editor (accessible exclusively on Shopify Plus). There are many more use cases for leveraging custom line item properties however, here are 3 to get you thinking:
- BOGO: You can offer a BOGO (“Buy One Get One”) depending on what products are in a customer's cart.
- Discounted Shipping Rates: You can offer a discounted shipping rate depending on the quantity of items in a customer's order.
- Hiding payment gateways: You can even hide payment gateways depending on if a specific product is within the customer's cart at the time of payment.
I’ve had fun solving challenges for many merchants using these custom line item properties and I want to give you 1 in-depth example of a real problem I solved to give you a sense of what can be achieved.
The task at hand: Discounting products that meet very specific conditions.
I once worked with a merchant who was advertising a specific product via paid ads and driving traffic to a dedicated landing page to convert as quickly as possible. The merchant also wished to upsell the customer to buy a larger order of the same product, once they had the product in their cart. To incentivize the upsell, the merchant wished to give the customer a unique discount that only worked in this very isolated scenario and nowhere else on the site.
In short - they had very specific discount logic and functionality in mind. All of which is not possible out of the box. To make the discount logic work, I needed to use special links + the Script Editor.
Here’s how I solved this problem:
To start - pre-populated cart links:
Within Shopify you can create a simple link which directly adds a product to a customers’ cart and can then redirect the customer to a specific landing page.
This feature is aimed at limiting friction for the customer and maximizing conversions. In my example above, the merchant ran a campaign promoting a specific product on a dedicated landing page - so we leveraged these special links in such a way that when users clicked the ad and were taken to the landing page, the product was already added to their cart.
My URL followed a similar structure as the below:
Here’s how you build a pre-populated Shopify cart link:
- To add a product to the cart: Replace `VARIANT_ID` with the variant ID of the product you want to add to cart.
- Replace `QUANTITY` with the amount of the product you want to add
- Replacing `KEY` with the line item property's key, replacing `VALUE` with the line item property key's value you want to use
- Redirect the customer to a specific landing page by replacing `LANDING_PAGE_PATH` with the path to the landing page you want the customer to visit.
- You could take it a step further and return to `/checkout` if you are doing a flash sale or live selling with the intention of having your customers buy the product as soon as possible.
Next: Script editor logic (3 steps)
Using the Script Editor app, I used logic to detect that a product was already added to the cart and that the customer was driven to the site from a specific landing page (“Step 1”).That’s important because the merchant did not want to discount the same product anywhere else on the site - and they did not want to simply create a duplicate of the SKU (for operational reasons).
Step 2 pertains to the upsell discount functionality we wanted to achieve. There, I’m trying to detect whether the customer has >2 of the product that was already in their cart, in their cart. If so, we can apply the bulk order discount. To detect that, we need to check whether the product variant of the product which was already in their cart matches the product variant of the extra products they’re adding to their cart. Once that’s confirmed, I built in logic to pass through the line item properties from the first product in cart to the other (identical) product additions.
Step 3 is about applying the appropriate discount when all conditions are met:
- They came from a specific landing page
- They already had a product directly in their cart.
- And they proceeded to add 2 or more of the same product to their cart.
Without further ado: Here’s the code:
Step 1: Adding custom line item properties to our product in cart when a user clicks our promotion. (Add this code to the landing page):
**Note:** You will want to replace `ref` with the line item property key you want to use and replace `landing-page-a` with the line item property key's value you want it to have if you need to use different values than this example. This is meant to be used within the product form so that it adds the line item property to the product if the customer chooses to add more from the landing page.
Step 2: Check whether a product is already in cart - If so, pass through the custom line item properties of that product to any future product additions where the product variant is identical to the product already in cart. (This is useful when you want to allow the customer to add the product from elsewhere but still capture the line item properties to know that the customer originally came from the landing page.)
if cart.item_count > 0
for line_item in cart.items
for variant in product.variants
if line_item.variant_id == variant.id
for property in line_item.properties
assign output = '<input type="hidden" name="properties[' | append: property.first | append: ']" value="' | append: property.last | append: '">'
Step 3: Unlock the discount if all conditions are met (line item properties are a match + >2 products in cart)
DISCOUNT_PERCENTAGE = 25
PROPERTY_KEY = 'ref'
PROPERTY_VALUE = 'landing-page-a'
Input.cart.line_items.each do |line_item|
price = line_item.line_price
properties = line_item.properties
if line_item.quantity >= 2 and properties.has_key?
(PROPERTY_KEY) and properties[PROPERTY_KEY] == PROPERTY_VALUE
discount = Decimal.new(DISCOUNT_PERCENTAGE) / 100.0
discount_amount = price * discount
line_item.change_line_price(price - discount_amount, message: '(25% off Discount)')
Output.cart = Input.cart
**Note:** This script only runs if PROPERTY_VALUE = ‘landing-page-a” which is where we’d validate that the customer came from the specific landing page.
BONUS: If you are NOT on Shopify Plus - you can unlock similar functionality to the above, but only using links and not the script editor.
Use this link in your promo:
This link adds the product to the customer’s cart and adds the discount code before redirecting back to the landing page. However, the limitation is that if they add more product to their cart, the backend cannot detect whether or not the customer came from this specific promotion. This means if the customer adds the product from elsewhere without the line item property the discount code could still apply. Essentially it would not be a complete solution to the original problem.
Custom line item properties are immensely powerful on Shopify Plus. They can help you control for many externalities as described in the example. Get familiar with them because once you do you’ll be able to apply similar logic to pass tracking parameters, control upsells and cross-sells and do lots of other cool things.