A Shopify coupon is a discount you configure in the admin under Discounts, and it comes in exactly four flavours: amount off products, amount off order, buy X get Y, and free shipping. Everything else you have seen on a storefront (tiered cart discounts, bundles, spend-and-get gifts, first-order popups) is one of those four wired up cleverly, or an app using Shopify Functions to go beyond them. Knowing which of the four you are actually building is the difference between a promo that works on the first try and a week of support tickets from customers whose code "doesn't work".
Below is how the mechanics work, how to create a code step by step, and the parts that bite: combination rules, code leakage, GST on the invoice, and the arithmetic on whether the promo paid for itself.
The four discount types, and what each one can and cannot do
Amount off products applies to specific products or collections, as a percentage or a fixed rupee amount. This is your category clearance tool. It discounts line items, which matters for reporting and for GST, because the reduction shows against the product on the invoice.
Amount off order applies to the whole cart subtotal. Fine for a flat "10% off everything" but it apportions across lines, which makes partial returns messier to refund correctly.
Buy X get Y is the most misunderstood. It handles BOGO, buy-2-get-1, and "buy a kurta, get a dupatta at 50% off". The trap: the "get" item has to already be in the cart or be auto-added, and the ratio applies per qualifying set. A customer who buys six of X on a buy-2-get-1 gets three free, not one, unless you cap the uses per order.
Free shipping can be limited by shipping rate value and by country. If you already run a free-shipping-above-₹999 rate in your shipping profile, a free shipping code on top of it does nothing visible and looks broken to the customer.
Gift cards can't be discounted. Subscription lines behave differently from one-time purchases. And Shopify caps the number of automatic discounts you can have active at once, so a plan that involves dozens of always-on automatic offers will hit a wall.
Creating a Shopify coupon, step by step
- Admin, then Discounts, then Create discount. Pick the type. Choose Discount code rather than automatic if you want a code customers type.
- Set the code itself. Type it by hand for campaigns (FESTIVE20), use generated codes for affiliates and influencers so each partner has their own. Uppercase, no ambiguous characters. Codes are case-insensitive at checkout but they display as you enter them.
- Set the value and the scope. Percentage or fixed amount; entire order, specific collections, or specific variants. Fixed amount on specific products applies per item by default, which is a common overspend.
- Minimum purchase requirement. Either a minimum subtotal or a minimum quantity of items. Set this against your AOV, not your gut. If AOV is ₹2,200, a ₹2,500 minimum is a real nudge; a ₹1,200 minimum is a giveaway.
- Customer eligibility. All customers, specific segments, or specific customers. Segments are how you keep a win-back code off the hands of people buying anyway.
- Usage limits. Total number of uses, and one use per customer. Turn on the per-customer limit for anything with a fixed rupee value. Note that per-customer limits rely on the customer account or email, so a determined abuser with three Gmail addresses gets three uses.
- Combinations. Decide now whether this code can combine with product, order, or shipping discounts. More on this below because it causes most of the mess.
- Active dates. Always set an end date. Festive codes that never expire end up on aggregator sites in March.
- Save, then test. Add a qualifying product, add a non-qualifying product, test on mobile, test with an address that triggers a different shipping rate. Two minutes of testing catches the buy-X-get-Y ratio error that would otherwise cost you a weekend.
Codes versus automatic discounts
A code needs to be entered. An automatic discount applies when the cart qualifies, with no field to fill. For anything threshold-based ("spend ₹2,999, get 15% off"), automatic wins every time, because a discount the customer has to remember to apply is a discount a third of them will miss.
Codes are for attribution: influencer links, email campaigns, a support agent smoothing over a late delivery, print inserts. If you cannot name who the code is for, it should probably be automatic.
One more thing on the checkout field. On standard Shopify checkout you can't remove the discount code box. That empty field is a leak: shoppers open a new tab, search for a code, and either find one on a coupon site or abandon. If your margins can't survive that, the answer is to run automatic discounts and keep generic public codes out of circulation entirely.
Stacking rules break more promotions than anything else
Shopify treats discounts in three classes: product, order, and shipping. One discount from each class can apply to the same order, and only if every discount involved has been marked as combinable with that class. Two order-level discounts will never stack. Two product-level discounts will never stack.
So the scenario founders ask for most ("10% sitewide, plus an extra 10% for email subscribers, plus free shipping") is not two order discounts plus shipping. It has to be rebuilt: one product-level discount on the collection, one order-level for the segment, one shipping. Or it needs a Functions-based app that computes the whole thing as a single discount.
Test the combination in a real cart before the campaign email goes out. We get the combination matrix wrong on the first pass often enough that testing is a standing step, not an optional one.
The arithmetic nobody runs before launching a 15% code
Take a store doing 1,000 orders a month, AOV ₹2,200, gross margin 45%. Contribution per order is ₹990, so ₹9,90,000 a month.
Now run 15% off sitewide. Every order uses it. The discount costs 15% of ₹2,200, or ₹330 per order, and contribution drops to ₹660. Total discount spend: ₹3,30,000.
To hold contribution flat at ₹9,90,000 with ₹660 per order, you need 1,500 orders. That is a 50% volume lift, from a 15% discount. Not impossible during a festive peak with paid support behind it. Very unlikely on a random Tuesday.
Flip it and the case improves fast. Make the same 15% conditional on a ₹3,500 minimum, and you are paying ₹525 on an order that carries ₹1,575 of margin instead of ₹990. The discount is bigger in rupees and cheaper in margin percentage terms, because the basket grew. Threshold discounts beat sitewide discounts on almost every P&L we have looked at.
COD, prepaid discounts and what they actually save
Prepaid discounts are the most common Shopify coupon in India and the most frequently mis-sized. The honest math, using the same store:
600 of 1,000 orders are COD. RTO on COD runs 24%, so 144 orders come back. Cost of an RTO: forward freight plus return freight plus packaging, call it ₹190 all-in. Plus the COD handling fee of roughly ₹35 per order and the remittance delay.
Per COD order you convert to prepaid, you save 0.24 × ₹190 = ₹45.60 of expected RTO cost, plus ₹35 of COD fee. About ₹81.
A 5% prepaid discount on ₹2,200 costs ₹110. You are down ₹29 on every order you successfully switch, and you also hand ₹110 to every customer who was going to pay online anyway. At 400 existing prepaid orders, that alone is ₹44,000 a month for nothing.
Size it at 2% (₹44) and the switch is profitable. Better still, charge a ₹50 COD fee instead of discounting prepaid. Same behavioural nudge, opposite cash flow. Customers grumble less than you expect, and Razorpay or your payment app can be configured so the prepaid path looks cheaper without you writing off margin across the whole book.
On GST: a discount recorded on the tax invoice at the time of supply reduces the taxable value, so the customer pays GST on the discounted amount. A cashback or reimbursement arranged after the invoice, not linked to it, generally does not. That distinction is why your finance team cares whether the coupon is applied in Shopify's checkout or refunded later as goodwill. Get your accountant's view before you build anything that pays out post-purchase.
Stopping code leakage
Type your brand name plus "coupon code" into Google. Whatever comes back is being applied to orders you were going to get anyway. Browser extensions auto-test code lists at checkout, and aggregator sites scrape newsletters within days.
What works:
- Unique per-customer codes instead of one shared string. Generated codes are tedious to distribute and impossible to scrape.
- Customer segment restrictions, so a leaked code fails for anyone outside the segment.
- Short active windows. A 72-hour code has almost no resale value.
- No round-number guessables. SAVE10, WELCOME10 and FIRST15 are tried automatically by extensions on every store.
- Own the SERP. A page on your own site listing current offers, kept honest and current, tends to outrank the aggregators for your brand plus coupon queries and sends that traffic back to you. Worth doing as part of ongoing content work rather than as a one-off.
When native discounts run out
The native four cover most retail promotions. They struggle with tiered cart discounts (5% at two items, 10% at three, 15% at four), true bundle pricing with mixed products, gift-with-purchase where the gift must be auto-added and locked, and customer-specific pricing for B2B or wholesale.
Those need Shopify Functions, which is the platform's current extension model for discount logic and the successor to Scripts on Plus. Either an app from the store or a custom function written for your store. Custom is worth it when the promo logic is a permanent part of how you sell, not a seasonal campaign, and when off-the-shelf apps would each add another script to your checkout. We build these as custom apps and Functions when the rule set is specific enough that no listed app fits, and we say so plainly when a ₹1,500-a-month app does the job instead.
If you are on Plus and still running legacy Scripts for discount logic, that migration is not optional and it is the kind of work that goes badly when rushed against a festive calendar. Our Plus team handles those.
Reading the numbers after the campaign
Shopify's Discounts report gives you orders, sales and discount amount per code. What it does not give you is incrementality, and that is the only number that matters. A code that appears on 800 of 1,000 orders has not driven 800 orders.
The cheap way to get closer: hold out a segment. Send the offer to 80% of a list, nothing to the other 20%, and compare revenue per recipient across the two groups over a 14-day window. If the holdout group converts at 1.8% and the offer group at 2.3%, your incremental lift is 0.5 points, not 2.3. Apply the discount cost only to the orders the lift explains, and most sitewide promos look considerably worse. Which is useful to know before you plan next quarter.
If you want a second pair of eyes on the discount structure before your next big sale window, our free store audit covers promo configuration alongside speed and checkout. Send the codes you plan to run and we will tell you which combinations will break.


