How to run a discount and a free gift on the same Shopify order
A spend goal that takes 10% off the order and a free gift that adds a product at 0.00 are two different discount classes, so they can combine on every Shopify plan once both offers opt in. This recipe fires both at $75.
- Spend goal
- Free gift
- $34.00
Restore Repair Shampoo
500ml / Qty 1
- $34.00
Restore Repair Conditioner
500ml / Qty 1
- $18.00
Gentle Body Wash
Qty 1
At $86.00 the cart shows a 10% saving line and the mini travel shampoo appears as its own line at no charge. The gift is a real cart line, so the shopper can see it, and it carries through to the order the same way any other item does.
How to set this up
- 1
Campaigns > New campaign
One campaign, two offers. Keeping them together means one schedule and one place to pause both.
- 2
Offer 1 > Offer type
Pick Spend goal. This is an order-class discount, so it takes a percentage off the whole order rather than off specific lines.
type = spend_goal
- 3
Offer 1 > Tiers
One tier at $75 for 10% off. Spend thresholds are stored in minor units, so $75 is 7500.
tiers[0] = minSpend 7500, percentage 10
- 4
Offer 2 > Offer type
Pick Free gift. The threshold lives on the tier and the gift itself lives on the offer.
type = free_gift
- 5
Offer 2 > Gift
Choose the mini travel shampoo as the gift, then add one or two backups. If the first candidate is out of stock the storefront gives the next one in the list, so the offer does not silently die when a gift sells out.
freeGift.giftVariantIds = [primary, backup]
- 6
Offer 2 > Limits
Leave the cap at one gift per order unless you deliberately want a shopper to be able to collect several.
freeGift.maxGiftsPerOrder = 1
- 7
Both offers > Stacking
On the spend goal turn on combining with product discounts. On the free gift turn on combining with order discounts. Each offer has to opt into the other class.
stacking.combinesWithOrderDiscounts = true
- 8
Preview
Simulate a cart just above and just below $75 so you can see the gift and the percentage appear together at the threshold, then publish.
Every setting, spelled out
These are the real configuration keys the offer is saved with, so you can check your own setup against this table field by field.
| Setting | Value | Config key |
|---|---|---|
| Offer 1 type | spend_goal | type |
| Offer 1 threshold | $75.00 (7500 minor units) | tiers[0].minSpend |
| Offer 1 reward | 10% off the order | tiers[0].rewardType |
| Offer 1 class | order | discountClasses |
| Offer 2 type | free_gift | type |
| Offer 2 threshold | $75.00, reward free_item | tiers[0].rewardType |
| Gift candidates | primary plus backups, first in stock wins | freeGift.giftVariantIds |
| Gift cap | 1 per order | freeGift.maxGiftsPerOrder |
| Offer 2 class | product | discountClasses |
| Combine (spend goal) | with product discounts: true | stacking.combinesWithProductDiscounts |
| Combine (free gift) | with order discounts: true | stacking.combinesWithOrderDiscounts |
See it built end to end
The episode is not up yet
We are recording this one. The written recipe above is complete, so you can build it today.
What Shopify does natively
Shopify has a native Buy X Get Y discount that can give a free product, and a native order discount for the percentage. Both can be set to combine, so a simple version of this is possible without an app.
Native Buy X Get Y triggers on quantity, not on cart spend, so "spend $75 and get this gift" cannot be expressed. There is also no fallback when the gift variant runs out: the native discount stops rewarding anyone.
Watch out for
- Both offers have to opt in. Setting the combine switch on only one of the two is the single most common reason a gift and a discount refuse to appear together.
- The gift is discounted to zero, not conjured into the cart out of nothing. Stock still has to exist, which is why the backup candidates matter.
- The 10% is calculated on the order, and the gift line is already at 0.00, so the gift does not inflate the percentage. Check this in the preview if your margins are tight.
- Two order-class discounts never combine with each other. If you already run a storewide order discount, this spend goal will compete with it rather than stack.
Common questions
- Why does my free gift disappear when I add a percentage discount?
- Because the two discounts are not set to combine. Combining is opt-in per offer and per class, and checkout drops one of them without warning when it is off.
- Can the shopper get more than one gift?
- Only if you raise maxGiftsPerOrder. The default is one gift per order, which is the safe setting for most campaigns.
- What happens if the gift is out of stock?
- The storefront gives the first in-stock candidate from the gift list. Adding one or two backups keeps the campaign alive through a sellout.
- Does the gift count toward the $75 threshold?
- No. The gift is discounted to zero, so it contributes nothing to the spend the threshold is measured against.
Related examples
Two product-class discounts on two collections, both applying in one cart, with the per-line rule spelled out.
One threshold, one gift added at no charge, with backups for when stock runs out.
A different gift at each spend threshold, with the highest qualifying gift awarded.
Build this in your own store
Every recipe in this library runs on the same server-side engine, so the cart total and the checkout total agree.