Purple light trails on a dark field, suggesting a promotional decision path between Shopify automatic discounts and Discount Functions

Shopify Automatic Discounts vs Functions for Black Friday Promos

Shopify Automatic Discounts vs Functions for Black Friday Promos

Sep 21, 2026

Octavian Contis 12 minutes

Share

The merchandising lead opens two cards on the same September board. Card one is a 20% sitewide automatic discount marketing already scheduled in the Shopify admin. Card two is the founder brief from Monday: buy two, take 40% off the third, free shipping over £75, and a gift pot once the cart hits £120.

Those are two different discount engines. Shopify automatic discounts and discount codes live in the admin Discounts page and cover percentage, fixed amount, Buy X Get Y, and free shipping. Discount Functions are app-defined types that run as Shopify Functions when the cart changes, so one rule can hit lines, the order, and shipping together, or apply tier and tag logic the native form cannot encode.

Choose the engine per promo before the freeze. Native automatic or code first when the rule fits. A public Function app or a Plus custom Discount Function only when the rule is genuinely custom, and only if you can test it on peak-sized carts while you still have time to roll back.

Introduction

This article teaches you to choose native Shopify automatic discounts or Discount Functions for each Black Friday promo by mapping stacking, BOGO, tiers, gift-with-purchase, Plus access, and peak performance before the freeze. Pairing a checkout banner with backend checkout logic is a different job, and it belongs in When to Use Checkout UI Extensions vs Shopify Functions.

The dated walk of checkout, inventory, fulfilment, and support gates sits in A Shopify Black Friday Readiness Checklist for Brands That Already Scale. This post stays on the discount method for the offers you already decided to run.

Merchant and developer threads in autumn keep returning to the same gap: a sitewide automatic that stacks with a code nobody re-checked, a gift that never appears as a line, or a Function that cannot see a discount code and a shipping country in the same run. The community signal is decision friction, not a missing campaign idea.

The decision merchants face

Shopify gives you three ways to reduce price, and they are easy to brief as one “promo”:

  1. Automatic discounts apply when the cart meets the conditions. The buyer never types a code.
  2. Discount codes apply when the buyer, an email, or an abandoned-checkout recovery message supplies the code.
  3. App discounts, including Discount Functions, appear as extra types on the Discounts page after you install an app. Shopify then executes the Function to calculate the reduction.

Native automatic and code types are the same four shapes: percentage, fixed amount, Buy X Get Y (or Spend X Get Y), and free shipping. Combination settings decide whether a product discount, an order discount, and a shipping discount can sit on the same order.

A Discount Function is a new type. Shopify’s Discount API can return product and order operations from cart.lines.discounts.generate.run, and shipping operations from cart.delivery-options.discounts.generate.run. One Function can therefore do work that would otherwise be three native discounts with three combination matrices.

That power is why teams brief Functions too early. A 20% collection automatic with combination boxes written down is faster to test, cheaper to staff, and easier to turn off on 2 December than a WASM module you still have in review.

Black Friday discount engine

YesNoPublicCustomNative automaticor code covers the rule?Admin automaticor discount codeDiscount Functionor Function appCustom appor public app?Install and testbefore the freezePlus custom Functionshipped before freezeBlack Friday discount engine
Black Friday discount engine

Criteria that actually matter

Write one row per Black Friday offer. The columns below are the job. If a cell is blank two weeks before the freeze, the offer is not ready.

Stacking and combination classes

Shopify applies discounts to the subtotal before tax. Combination is class-based: product, order, and shipping. Two product discounts do not stack the way two different classes can.

Community prep threads keep landing on the same September homework: list every code, automatic, and free-shipping rule that will be live, then inspect each pair. A 20% automatic on the collection plus a 25% welcome code can become a 40% effective cut when both combination boxes stay ticked. That is a written policy, or it is an accident.

Discount Functions still participate in that model. The Function declares discount classes. Those classes decide which targets Shopify runs and how the Function sits next to native automatics and codes. A custom type that claims product, order, and shipping in one owner can hide the pair you thought you had isolated.

Replay last year’s peak SKUs against this year’s planned stack on a spreadsheet before you trust the admin preview. Cost per item has to be on the variant, or no report will tell you whether the pair still leaves contribution.

BOGO, tiers, and gift-with-purchase

Native Buy X Get Y covers “buy two, get the third at a set percentage or amount” when the rewarded item is already a catalogue line the buyer can add. Spend X Get Y covers a threshold on the same shapes.

The brief leaves native once the third unit needs a different rate from the sixth, once customer tags change the band, or once the gift is a SKU that should appear only after the threshold. Volume apps that only expose static percentage steps hit the same wall; a Discount Function can encode a formula or a tag table the admin form cannot.

Gift-with-purchase is the usual trap. Zeroing a qualifying item the buyer already added is a discount job. Inserting a new gift line with its own title and image is a cart-shape job. Cart Transform can expand, merge, and update lines. Adding a brand-new line is still a requested gap, which is why gift apps still mix Functions with storefront cart calls. If the founder wants a pot that “just appears”, name the add path on the row before ads mention the threshold.

Codes versus automatic

Automatic discounts are the right default for a sitewide or collection sale the whole weekend. Codes are the right default when the offer is for a list, an affiliate, or an abandoned checkout, because you can expire the code without touching the automatic that still sits on the storefront.

Mixing both is where BFCM goes quiet-then-loud. Recovery emails can attach a code to a cart that already received the automatic. Combination settings decide whether that is a second reduction or a rejected code. Test guest checkout, logged-in checkout, and the recovery path on the same SKU.

A Function that must reject a code for some shipping countries has a second constraint. The cart-lines discount target can see entered codes and often cannot see delivery address. The delivery-options target can see country and may not run once a code is present. If the Black Friday rule needs both inputs in one decision, treat that as a Function-design risk and settle it in October, or drop the geo rule from the promo.

Plus versus a public Function app

Stores on any plan can install a public App Store app that contains Functions. Only Shopify Plus can run a custom app that contains Shopify Function APIs. Shopify Help states the same split for building your own custom discounts app.

Checkout UI extensions, payment customisation, and delivery customisation remain Plus checkout work. They do not unlock a better percentage automatic. If the plan question is still open, use Choosing the Right Shopify Plan before you treat an upgrade as a November discount patch.

A public Function app is still a production dependency at peak. You inherit the app’s WASM budget, its input queries, and its support hours. Prefer an app you already run in ordinary weeks over a seasonal discount install you will forget in January.

Performance at peak

Shopify executes Discount Functions inside checkout. Delays and failed runs affect whether the buyer can purchase. Shopify recommends Rust for large carts because JavaScript Functions are more likely to hit instruction or memory limits when the cart is full.

Function order is fixed: cart lines, Cart Transform, line discounts, then later delivery discounts and validation. A slow Discount Function sits on the purchase path, in front of fulfilment and payment customisation. Peak weekend is a poor first load test.

If you ship a custom Function, replay carts with last year’s line counts, plus a worst-case gift or bundle expansion, and read the Function run logs before the freeze. If you cannot name the last successful run against a large cart, the offer still belongs on a native automatic.

Framework

Use this matrix on the promo sheet. One row per offer. The recommendation is the first column that the rule actually needs.

CriterionNative automatic or codePublic Discount Function appCustom Discount Function (Plus)
Rule shapePercentage, fixed amount, Buy X Get Y, free shippingTiers, tags, bundles, or mixed product and shipping in one type the app already shipsBrand-specific formula, membership table, or a class mix no public app can configure
StackingWrite product, order, and shipping combination pairs; test each pair on a live cartRead the app’s discount classes and how they sit next to native automaticsDeclare classes on purpose; one Function can replace three native discounts
BOGO and tiersOne rewarded rate, rewarded item already in catalogueStepped volume or category thresholds the app exposesFormula or tag-driven bands the admin cannot store
Gift-with-purchaseDiscount or zero a line the buyer already addedApp that owns the gift add path and inventoryFunction plus Cart Transform or cart API, with the add path named
Who can build itAny plan, Discounts pageAny plan, App Store installPlus custom app only
Peak riskCombination mishap, recovery code stackingApp WASM limits, leftover seasonal installUntested large-cart runs, input-query gaps, deploy during freeze
Choose this whenThe brief fits a native type and you can write the pairsThe app already matches the brief and has run on this storeThe brief is unique and the Function is in production before the freeze

Recommendation by scenario

Sitewide or collection percentage

Use a native automatic. Put the collection or product list on the discount, write the combination boxes, and keep marketing codes on a separate class or with combinations off. This is the card you can schedule, screenshot, and turn off on 2 December without a deploy.

Simple BOGO on the same SKU

Use native Buy X Get Y. “Buy two, get the third at 40%” is an admin rule when the third unit is the same product. Save Functions for a different rate on unit six, or for a gift that is a different SKU.

Tiered volume or member pricing

Start with a public Discount Function app you already trust if the tiers match its configuration. Commission a custom Discount Function on Plus only when the table is brand-specific and the app would need a rewrite. Either path needs a large-cart Function log before paid traffic.

Gift-with-purchase plus free shipping

Split the brief. Free shipping over £75 is a native shipping automatic or code. The gift pot is a separate row: native only if the pot is a catalogue item the buyer adds, otherwise an app or Function whose add path you have already tested with inventory. Do not hide both rules inside one untested Function the week ads start.

Code for a list, automatic for the weekend

Keep the weekend sale automatic. Give the list a code on a different class, or with combinations disabled against the automatic. Test abandoned-checkout recovery on a cart that already received the automatic, because that is the path that silently stacks.

If checkout itself is dropping purchases, fix that path first with How to Fix Shopify Checkout Abandonment When Your Funnel Looks Healthy. A Function that calculates a perfect discount still fails if Shop Pay or the payment step cannot complete.

The brief arrived in November

Simplify. Peak week is for combination audits and live test orders, not a new discount type. Park the gift pot or the tag table until January. The freeze in the readiness checklist exists so you stop inventing engines while the warehouse is already loading.

What to lock before the freeze

Put these dates on the same sheet as the offers. They sit beside the inventory work in How to Stop Shopify Oversells During Black Friday Flash Sales, because a gift SKU with no available-to-sell number is an oversell you scheduled as a promo.

  • Black Friday minus 21 days: every offer has an engine (native automatic, code, public Function app, or Plus custom Function) and a named owner.
  • Black Friday minus 14 days: combination pairs tested on guest, Shop Pay, and recovery; Function run logs exist for a large cart; gift add path proven with inventory.
  • Black Friday minus 10 days: live test orders show the expected discount lines and shipping, with no staff workaround.
  • Freeze: no new discount apps, no Function deploys, no combination edits except a documented hotfix with rollback.

Seasonal badge, timer, and gift apps are easy to install in October and easy to forget in January. If the discount engine is an app you only need for three weeks, write the uninstall date on the same row as the start date.

This reflects patterns we see regularly across the Shopify merchant and developer community.

Conclusion

You can now choose native Shopify automatic discounts or Discount Functions for each Black Friday promo. Map stacking classes, BOGO and tier shape, gift-with-purchase add path, code versus automatic, Plus versus a public Function app, and peak Function performance, then freeze whatever you did not finish.

Start with the admin Discounts page when the rule fits. Use a Function, or a Function app, when one type must do work the native form cannot, and only when the run has already survived a large cart. The founder brief can wait until January if the engine is still a spec.

If the promo sheet needs a Discount Function or a checkout-adjacent build scoped and shipped before the freeze, start with Shopify UI Extensions and Functions or book a discovery call and we will map each offer to an engine the store can actually run on the Friday.

Frequently Asked Questions

Shopify automatic discounts are native admin rules: percentage, fixed amount, Buy X Get Y, or free shipping, applied at cart and checkout when the buyer meets the conditions. Discount Functions are app-defined discount types that run as Shopify Functions when the cart changes, so one rule can reduce line items, the order subtotal, and shipping together, or apply volume, tag, and membership logic the admin form cannot encode. Automatic discounts belong on the Discounts page. Functions belong in an installed app, then appear as a custom discount type on that same page.

You can install a public App Store app that ships Discount Functions on any Shopify plan. Only Shopify Plus can run a custom app that contains Shopify Function APIs, including a Discount Function you commission for one brand. Checkout UI extensions, payment customisation, and delivery customisation stay Plus-only, and those surfaces are a different job from promo math. If the Black Friday rule already exists in a public Function app, Plus is not the switch that unlocks it.

Shopify can combine a product discount, an order discount, and a shipping discount when each discount’s combination settings allow the pair. A 20% automatic product discount plus a 25% order code can legally stack if both boxes are ticked, and that pair is where Black Friday margin usually disappears. List every code, automatic, and free-shipping rule that will be live in November, then test the pairs on a live cart before the freeze. Treat an unticked combination box as a written decision, not a leftover default.

Use a Discount Function when one promotion must apply different rates by quantity, customer tag, or spend band, or when one rule must discount products and shipping together. Native Buy X Get Y covers a simple free or discounted item after a quantity or amount, and it fails once the third unit needs a different rate or the gift is a SKU that is not already in the cart. Ship the Function, or the public app that wraps it, early enough that you can replay last year’s peak cart sizes against the WASM run. If that work still sits in a spec on 1 November, simplify the offer to a native automatic or code.

Native Buy X Get Y can discount or zero a qualifying item the buyer already added, which is enough for “buy two, get the third half price” when the third unit is the same catalogue item. A free gift that must appear as a new line, with its own image and a zero or token price, usually needs a Discount Function, a Cart Transform, or a gift app. Cart Transform can expand, merge, and update lines; adding a brand-new gift line is still a platform gap, so most gift-with-purchase apps still use cart APIs or mixed Function plus storefront work. Lock the gift SKU and the add path before ads point at the threshold.

Leave Discount Functions, checkout Functions, and new discount apps inside the same freeze you use for theme deploys. Peak traffic is when a WASM timeout, an input-query miss, or a combination change shows up as a missing discount or a double reduction. If a hotfix is unavoidable, keep one owner, a rollback to the last tested Function version, and a live test order on guest checkout and Shop Pay before you raise paid spend. Park unfinished custom discount work until January unless the live checkout already depends on a fix you can reverse in minutes.

Discount Functions calculate price reductions on cart lines, the order subtotal, and shipping rates. Checkout Functions such as payment customisation, delivery customisation, and cart validation change how checkout behaves, and they sit on Shopify Plus with Checkout UI Extensions. Pairing a discount result with a banner or progress bar is a display job, covered in the checkout UI versus Functions guide. Keep the Black Friday promo decision on the discount method first, then decide whether the buyer also needs a checkout message.

Related Articles