Matrix Bundles

Discount rules

A rule takes a percentage off the products you choose, and two rules on the same item are added together rather than one of them winning, unless you set a rule not to add. This page is how they are set up.

What a rule is

A rule is one sentence: take this much off these products. You give it a name for yourself, a percentage, the line a shopper reads at checkout, and the products it applies to — product tags, collections, or both.

Two things are optional. A rule can be limited to carts that carry a particular detail, so an offer meant for one place stays there. And a rule can be allowed to come off bundles, which is off unless you turn it on.

Each rule also says whether it adds to other offers on the same item. It does unless you choose otherwise.

Every rule is a draft until you set it live. A draft takes nothing off anything. Your rules sit on one screen, Discounts, with one setting above them that applies to all of them: the most that can come off any single item.

Why rules are added together

Unless a shop is on Shopify Plus, only one product discount lands on a cart line. So if you run two offers that both cover the same jar of cream, one of them applies and the other is thrown away. Shoppers see the smaller saving they were expecting and you cannot tell them why.

This app adds them up instead. Every rule that lands on an item is added together and the total comes off once, as one discount. A rule taking 10% and another taking 10% make 20% off that item, not 10%.

The adding is done in whole hundredths of a percent, so 10 and 10 is exactly 20 and never 19.999. Percentages are added, never multiplied.

The shopper reads one message, not several: the one belonging to the largest rule that counted. If two rules are the same size, the one higher up your list wins.

A rule set to “Doesn’t add to other offers” is the exception. It is never added to anything. The item gets that rule or the other rules added up, whichever is bigger, never both. If they come to the same, the added-up rules win. If two rules that don’t add land on one item, only the bigger counts, and on a tie the one higher up your list. The most off any one item still applies to whichever wins.

None of this has been through a real checkout yet. Both halves of the app — the panel that shows you the money and the code that takes it — are held to the same answer by a test that runs each of them over the same carts. That proves they agree with one another. It does not prove what Shopify does with either of them on a live shop.

Setting one up

Discounts is a screen in the app with your rules on it. Open one and it is a single form. At the top of the form is a plain sentence saying what the rule does, which rewrites itself as you change the settings under it.

Every setting on that form, in the order it appears. The name in brackets is what the setting is called in the rule the app stores — useful when you read the next section, and not needed otherwise.

  • Name name — What you call the rule. For you — shoppers never see it. Up to 120 characters.
  • They save (%) percentage — How much comes off. A number from 0 to 100, with at most two decimal places. A rule set to 0 saves nothing, and the app says so rather than refusing it.
  • What it applies to products — A product tag, or a collection. Add more rows and an item in any of them gets the rule. A collection is chosen from a list rather than typed, because the checkout compares it exactly and a handle or a bare number never matches. A rule with nothing chosen is refused — it would otherwise reach every item in the cart.
  • Only for carts that come from somewhere in particular when — Off by default, and off means the rule applies to every cart including your website’s. Turned on, it takes the name of a cart detail and the value it has to have, and the rule only applies to carts carrying it. A cart without that detail gets nothing from the rule. A shopper can set a cart detail too: it is a cart attribute, and anyone can change one through your shop’s /cart/update.js address. So this decides where a rate turns up, not who can have it. Do not use it to keep a rate private.
  • With other offers when.alone — Two answers. “Adds to other offers on the same item” is where a new rule starts: the form says “10% and 15% on the same item come off as 25%, up to the most you allow off any one item.” “Doesn’t add to other offers” keeps the rule apart: “The shopper gets this offer or the other offers added up, whichever is bigger, never both.” Use it for a rate that must not also take a sale, such as a trade price.
  • Also take this off bundles on_bundles — Off, and off is how it is stored. Switching discounts on must never quietly change the price of a bundle that is already selling. Turn it on and the app warns you — see Rules and bundles below.
  • Message at checkout message — The line the shopper reads beside the saving. Your words, up to 120 characters, with no space at either end. There is no wording the app can put there for you.
  • Status status — Draft — nothing comes off yet. Or Live — shoppers get this now. A new rule starts as a draft.

Deleting a rule removes it from the app and shoppers stop getting it. Orders already placed do not change.

The same rule written out

The app keeps your rules on your own shop as one small document, and the checkout reads that document. You never type it — the form writes it for you — but it is the exact shape of what you set, and it is the clearest way to see how the pieces fit.

{
  "schema_version": 1,
  "cap": 50,
  "rules": [
    {
      "id": "spring-serums",
      "status": "live",
      "type": "percentage",
      "name": "Spring serums",
      "percentage": 10,
      "message": "Spring offer on serums",
      "products": [
        { "mode": "tag", "value": "serum" },
        { "mode": "collection", "value": "gid://shopify/Collection/123456789" }
      ],
      "on_bundles": false
    },
    {
      "id": "trade-price",
      "status": "live",
      "type": "percentage",
      "name": "Trade price",
      "percentage": 30,
      "message": "Trade price",
      "products": [
        { "mode": "tag", "value": "trade" }
      ],
      "when": { "alone": true },
      "on_bundles": false
    }
  ]
}
  • cap — the most that can come off any one item, once every rule on it has been added up. It is 50 unless you change it. See below.
  • type — always “percentage”. It is written down even though there is only one kind, because the checkout skips a rule of a kind it does not recognise. That is what lets other kinds be added later without half-applying anything at a live checkout in the meantime.
  • products — one row per tag or collection. A collection is a full Shopify collection id, which is why the form makes you pick it from a list.
  • when — left out on a rule that adds to other offers, unless you use “only for carts that come from somewhere in particular”; then it is { "attribute": the cart detail, "equals": its value }. A rule that doesn’t add always has one, even with no cart detail: { "alone": true }, as on the second rule above. With a cart detail it becomes { "cart": { "key": the cart detail, "equals": its value }, "alone": true }.
  • schema_version — which shape this document is in. A document from a newer version of the app is ignored whole rather than half-read.

The app also keeps a short list of the cart details your rules look at. That list only ever grows. A detail keeps its place once it has been used, because the checkout is handed the value that sits in a place and never told which detail put it there — so a detail that moved places would compare the wrong thing under the right name.

Anything in this document the app does not recognise is refused rather than kept or quietly dropped. A setting it drops is one you believe you saved; a setting it keeps is one the checkout will not understand. Both fail silently, which is the failure this app is built to avoid.

There is no way to send this document to the app. Matrix Bundles has two doors that other software can talk to, and none of their operations sends or changes a discount rule. Discount rules are set on the screen and nowhere else.

Most off any one item

One setting for the whole shop, beside your list of rules. It is the ceiling on the total after every rule that lands on an item has been added up — not a limit on one rule.

It is 50% unless you change it, and it can never be more than 100%. Three rules of 25% on one jar come to 75%; with the ceiling at 50%, the shopper gets 50%. Test a cart and that line is marked capped, so you can see it happen before it is live.

The box takes 1 to 100, so the ceiling cannot be set to 0. To stop your rules taking anything off, set each one back to Draft.

If the ceiling is ever there but unreadable, nothing comes off anywhere on the shop, and not just on one rule. A ceiling is not something the app will guess at.

Rules and bundles

A bundle’s price is not a discount. It comes off inside the cart, when the chosen items are merged into one line, so it uses none of the discount slots Shopify gives your shop and it never competes with a rule.

A bundle reaches a discount as one line at its bundle price, so anything a rule takes off comes on top of the bundle saving. The rule is checked against the bundle’s hidden product, not the products inside it: a collection that only the products inside are in does not reach the bundle.

So a rule takes nothing off a bundle unless you turn on “Also take this off bundles”, and even then it reaches only a bundle whose hidden product has the rule’s tag or is in its collection. The rule screen lists which bundles a rule reaches and says how to include one. The switch is off, and off is how it is stored, so turning discounts on cannot change what a bundle already selling charges. A rule coming off a bundle this way has not yet been seen at a real checkout.

Turn it on and the app warns you, in these words: “The bundle builder on your product pages shows the bundle saving only, so shoppers see a smaller saving there than they pay at checkout.” The shopper is charged less than the page quoted, which is the safer direction but still a surprise.

The limits

Every one of these is enforced at the save. None of them is a guideline, and none of them is something you will discover later at a checkout.

  • 9,500 bytes for all your rules together — Shopify never hands the checkout a value over 10,000 bytes. Over that it hands it nothing, which reads as “no rules” and switches every discount off without a word anywhere. The app refuses the save first. Bytes, not characters — accented and non-Latin text costs more than it looks.
  • 100 different product tags, and 100 different collections — Counted across every rule on the shop, drafts included. It is a hard Shopify limit, and going over it fails every run at checkout rather than just one rule. A warning starts at 80.
  • Two cart details, for the whole shop — That is how many the checkout can be asked about. A detail keeps its place once it has been used, so deleting the rule that used one does not free it up. A rule naming a detail with no place left is refused at the save, rather than saving cleanly and then quietly never applying.
  • 120 characters for a rule’s name, and 120 for the checkout message — The message is the one a shopper reads, so it is kept short on purpose.
  • Percentages: 0 to 100 for a rule, two decimal places — Anything more exact is refused rather than rounded, so the figure on your screen and the figure at the checkout can never be two different numbers. The ceiling has the same two decimal places, and its box takes 1 to 100.

What it refuses to save

The app would rather refuse a save than store something it cannot act on, and it tells you why in a sentence. These are those sentences, exactly as the app says them. Anything in angle brackets stands for a number or a value the app fills in.

About one rule. Each one arrives with the rule’s own name in front of it, so you know which rule it means:

  • give this rule a name, so you can tell it apart from the others.
  • the name is longer than 120 characters.
  • its status is “<what you sent>” — it must be draft or live.
  • it is a “<what you sent>” rule, and the checkout only knows: percentage.
  • write the line the shopper sees at checkout. There is no wording we can put there for you — it is the words your customers read.
  • the checkout line starts or ends with a space.
  • the checkout line is longer than 120 characters.
  • it takes <n>% off — that must be a number between 0 and 100.
  • <n>% is more exact than the app can work in. Use at most 2 decimal places.
  • choose which products this applies to. A rule that matches nothing would apply to everything.
  • product <n> has nothing chosen.
  • product <n> matches by “<what you sent>” — the app knows: tag, collection.
  • product <n> points at something that is not a collection. Choose the collection again from the list.
  • its “only when” needs the name of the cart detail to look at.
  • its “only when” needs the value that cart detail has to have.
  • this rule needs an id.
  • this rule holds something the app doesn’t know: <the extra settings>.

About all your rules together, or the shop’s ceiling:

  • Set the most that can come off any one item. It is 50% unless you change it, and it can never be more than 100%.
  • The most off any one item is <n>% — it must be between 0 and 100%.
  • The most off any one item is <n>% — that is more exact than the app can work in. Use at most 2 decimal places.
  • Two rules share the same id: <the ids>. Each rule needs its own.
  • Your rules name <n> different tags. Shopify caps that list at 100, and going over stops discounts working at all.
  • Your rules name <n> different collections. Shopify caps that list at 100, and going over stops discounts working at all.
  • Your rules look at <n> different cart details (<the details>). The checkout can be asked about 2.
  • These rules look at <n> different cart details, and the checkout can be asked about 2. A cart detail keeps its place once it has been used, so removing an old rule does not free one up.
  • Your discount rules come to <n> bytes. Anything over 10,000 bytes is never sent to the checkout at all, so every discount would quietly stop. The limit here is 9,500.
  • These discount settings hold something the app doesn’t know: <the extra settings>. Saving them could mean the store behaves in a way this screen never showed you.

And these are saved, but the app says them anyway, because each one is a way of running that is legal and probably not what you meant:

  • “<your rule>” takes 0% off, so a shopper sees no change.
  • “<your rule>” takes <n>% off, but the most off any one item is <n>%, so shoppers get <n>%.
  • “<your rule>” also comes off bundles. The bundle builder on your product pages shows the bundle saving only, so shoppers see a smaller saving there than they pay at checkout.
  • Your rules name <n> different tags, of a limit of 100.

What happens at checkout

A live rule the checkout cannot act on is skipped whole rather than half-read. Either it applies or it does not, and the app tells you which rule was skipped and why:

  • This rule is a draft, so it is not live.
  • This rule is set up in a way the app doesn’t know, so it is not used.
  • The checkout is not set up to look at “<your cart detail>” yet, so this rule takes nothing off. Save your rules again to set it up.
  • This rule only applies when the cart has <your cart detail> set to “<your value>”, and this one doesn’t.
  • This rule only matched bundle lines, and it is not set to come off bundles.
  • Your discount settings date from before the app could tell bundles apart, so this rule takes nothing off yet. Save any rule once to fix that.

A shopper is never blocked and never told anything is wrong. A cart that matches no rule is simply charged ordinary prices.

How it sits in Shopify

Nothing is made on your shop when you install the app, and nothing is made when you write a rule. Your first live rule makes one automatic discount in Shopify, called “Matrix discounts”, and every rule you write shares it.

That is on purpose. A discount sitting idle would take one of your shop’s automatic discount places while you were only having a look.

Shopify lets a shop run 25 automatic discounts at once, and discounts made by apps count towards the 25. Your rules use one of them however many you make. Bundle prices are not discounts and use none of them.

Shopify asks your permission once, when you press “Turn on discounts” — not when you install the app. You get one prompt. A shop that only wants bundles is never asked for the right to make discounts, and nobody has to re-approve anything they already agreed to.

Testing a cart first

There is a button on the rule form called “Test this cart”. It builds a cart from your own products, prices it under the rules on screen, and shows five columns: the item, its price, the price after any bundle price, what comes off, and what is charged.

They are in that order because that is the order the platform works in — the cart merge runs first, then discounts — and getting that order the wrong way round is the usual reason a figure looks wrong.

Nothing is live until you save. The panel works none of the figures out for itself — it runs your rules through the app’s own engine, and a test holds that engine and the one at the checkout to the same answer over a long list of carts.

What it costs

Discount rules are on the Core + Discounts plan: $29 a month with a 14-day free trial. The Free and Core plans do not have them. Free is for one live bundle, and Core is $19 a month with a 14-day free trial.

You choose a plan on the app’s plan page in Shopify, where you see the price before you are asked to pay anything. Discount rules ask Shopify for one extra permission, the first time you press “Turn on discounts”.

Nobody’s price changes without them agreeing to it. Shopify will not move a shop onto a different plan on its own, and neither will we.

Questions

The Matrix Bundles manual covers bundles, which are live today. The support page answers the questions merchants ask most often.

If yours is not there, email support@matrixhealthgroup.co.uk and a person will answer.