Discount code mapping
StagingDiscountCode flattens Shopify’s nested discount shape into a
handful of fields. You set one discount value flavor
(percentage, amount, or freeShipping) plus optional minimum
requirements and combination rules.
Quick reference — minimum loadable code
{
"original_id": rule_id,
"title": rule_name,
"code": coupon_code,
"startsAt": from_date,
"percentage": discount_percent / 100
}Identity & schedule
titlestringInternal name shown in Shopify admin.
"title": rule_namecodestringThe redemption code customers enter at checkout.
"code": coupon_codestartsAtstring (ISO8601)When the code becomes active.
"startsAt": from_dateendsAtstring (ISO8601)When the code expires. Omit for codes that never expire.
Discount value
Set exactly one of percentage, amount, or freeShipping. Setting more than one is undefined behavior.
percentagenumberDecimal between 0 and 1 — 0.25 means 25% off. Not 25.
"percentage": discount_percent / 100amountnumberFixed money amount off (in currencyCode).
"amount": discount_amount,
"currencyCode": "USD"currencyCodestringCurrency for amount. ISO 4217 (USD, EUR, …). Required when
amount is set.
freeShippingbooleantrue for a free-shipping discount code. Mutually exclusive with
percentage / amount.
appliesOnEachItembooleanFor fixed-amount discounts: true means “$X off each qualifying
line item”, false means “$X off the order subtotal”. Defaults to
false if not set.
Limits
usageLimitintegerTotal redemptions allowed across all customers. null = unlimited.
"usageLimit": uses_per_coupon > 0 ? uses_per_coupon : nullappliesOncePerCustomerbooleanIf true, a single customer can use the code only once.
recurringCycleLimitintegerFor subscription discounts: number of billing cycles the discount
lasts. 0 means indefinite.
Minimum requirements
Set one (subtotal OR quantity), both, or neither.
minimumSubtotalnumberMinimum order subtotal required for the discount to apply.
"minimumSubtotal": minimum_amountminimumQuantityintegerMinimum quantity of qualifying items required.
Scope
allItemsbooleandefault trueWhether the discount applies to all items. Defaults to true. The
staging model only supports the all: true items selector today;
narrowing to specific products / collections needs custom work
post-migration.
appliesOnOneTimePurchasebooleanappliesOnSubscriptionbooleanCombination rules
Whether this discount stacks with other discount classes. Set at least one to enable combinesWith.
orderDiscountsbooleanStacks with other order-level discounts.
productDiscountsbooleanStacks with product-specific discounts.
shippingDiscountsbooleanStacks with shipping discounts.
Patterns
Magento percentage cart rule → Shopify code
{
"original_id": rule_id,
"title": rule_name,
"code": coupon_code,
"startsAt": from_date,
"endsAt": to_date,
"usageLimit": uses_per_coupon > 0 ? uses_per_coupon : null,
"appliesOncePerCustomer": uses_per_customer = 1,
"percentage": discount_amount / 100,
"minimumSubtotal": minimum_amount > 0 ? minimum_amount : null,
"allItems": true
}Fixed-amount-off subtotal
{
"original_id": rule_id,
"title": rule_name,
"code": coupon_code,
"startsAt": from_date,
"amount": discount_amount,
"currencyCode": store_currency,
"appliesOnEachItem": false
}Free shipping over a threshold
{
"original_id": rule_id,
"title": "Free shipping over " & $string(threshold),
"code": coupon_code,
"startsAt": from_date,
"freeShipping": true,
"minimumSubtotal": threshold
}Code that stacks with everything
{
…,
"orderDiscounts": true,
"productDiscounts": true,
"shippingDiscounts": true
}Gotchas
Percentage is a decimal between 0 and 1. 0.25 for 25%, not
25. The most common mapping bug — load succeeds and the merchant
later discovers customers redeemed for 2,500% off.
- One discount value flavor only. Setting both
percentageandamountproduces undefined behavior in the load. Pick one per code. amountwithoutcurrencyCodeloads but Shopify infers the shop’s primary currency, which can be wrong for multi-currency shops. Always set both.combinesWithdefaults tofalsefor every class. If you don’t set any oforderDiscounts/productDiscounts/shippingDiscounts, the code combines with nothing.- Code uniqueness. Two discount codes with the same
codecollide on Shopify. If your source allows duplicates (some platforms do — different rules sharing the same code), resolve in the mapping by suffixing with the rule ID. - Scope today is “all items”. If the merchant’s source rule was scoped to specific products or categories, that nuance is lost. Surface a warning to the merchant; the code still applies but more broadly than the source.
- Subscription cycles.
recurringCycleLimitonly matters if the destination Shopify store has subscription apps — for plain one-time purchases, it has no effect.