Blog · · 8 min

How to raise average order value on a store you coded yourself

Average order value moves through four mechanics, and each one acts on a different share of orders: the quantity tier on the product page, the shipping threshold in the cart, the named complement above the totals, and the addition after payment. On a custom store all four are components, not subscriptions.

By

Average order value is the one number a small store can move without more traffic. It has four levers, they act at four different moments, and they compound because they act on different orders:

MechanicWhere it livesActs onWhat it asks of the buyer
Quantity tiersproduct pageevery order, before a cart existsa choice they were making anyway
Free-shipping thresholdcartorders already near the thresholdone more item, framed as saving
Named complementcart, above the totalsthe confirmation momentone tick, small amount
Post-purchase additionafter paymentorders already wonone tap, zero risk

If you have none of them, build them in that order. The first acts on 100% of orders and asks for nothing extra, which makes it the cheapest thing you will ever build.

Why start with the quantity tier?

Because it is the only one of the four that operates before the buyer has decided how much to spend, rather than trying to change a decision already made.

A single price with a stepper asks: do you want this. A tier selector asks: how many do you want, and here is what each answer costs per unit. Those are different questions, and the second one has no "no" in it. The buyer who was going to buy one is now choosing between one, two and three.

The arithmetic below is a worked example, not a measurement — plug your own numbers in.

// A worked example. Substitute your own unit cost and mix.
const unit = 2400;             // €24.00 sale price
const cost = 900;              // €9.00 landed cost
const tiers = [
  { qty: 1, pct: 0 },
  { qty: 2, pct: 12 },
  { qty: 3, pct: 20 },
];

for (const t of tiers) {
  const revenue = unit * t.qty * (1 - t.pct / 100);
  const margin = revenue - cost * t.qty;
  console.log(t.qty, (revenue / 100).toFixed(2), (margin / 100).toFixed(2));
}
// 1  24.00  15.00
// 2  42.24  24.24
// 3  57.60  30.60

Three units at a 20% discount still carries more than twice the gross margin of one unit at full price. That is the whole case for the mechanic, and it is arithmetic rather than persuasion. The failure mode is a discount curve steep enough that the top tier earns less margin than the middle one — worth checking before you pick the percentages, because it is easy to do by accident.

![Three kraft boxes on dark slate under hard light, stepped in a diagonal, each carrying a small punched brass tag reading 1, 2 and 3, the third tag sitting slightly proud of the others.](/blog/trois-boites-etagees.webp "The tier selector is not a discount. It replaces the question do you want this with the question how many, and the second question has no no in it.")

How do the four mechanics avoid colliding?

They collide when two of them ask for the same increment at the same moment. Three rules keep them apart.

One ask per screen. The product page asks about quantity. The cart asks about the threshold or the complement, never both in the same viewport. The confirmation asks about the addition. A buyer facing two upgrade prompts at once takes neither.

Downstream mechanics inherit upstream success. A buyer who took the three-unit tier arrives at the cart already past the shipping threshold, so the bar congratulates rather than nags. That is the intended interaction, not a wasted opportunity.

The complement is named, and it is not the same product. A cart offering "add one more of what you already added" after the product page offered exactly that is the store asking twice and getting quieter each time. The complement is a different object, chosen by use — the reasoning is in frequently bought together, done right.

What does this cost on a custom store?

Nothing recurring, and that is the structural difference from the app route.

On a hosted platform, each of these four mechanics is typically a separate app with a monthly fee, and several of the upsell apps in that category price per order rather than per month — you pay on orders the widget did not influence, which is the complaint that shows up most often in their public reviews. On a store you coded, they are four components in your repository.

Rented widgetComponent you own
Cost shapemonthly, sometimes per orderone build
Removaluninstalling can take page content with itdelete a file
Stylingtheir design system inside your pageyours
Dataleaves your storestays
What breaks on theme updateunknownnothing, it is your code

The trade goes the other way too, and it is worth stating honestly: a rented widget exists this afternoon and a component you own does not. If you have never shipped any of the four, the fastest path to knowing whether they matter for your store is to build the tier selector, which is the cheapest, and look at the result before building the other three. The full comparison is in replace Shopify apps with code you own.

What is the measurement that tells you it worked?

Average order value alone will lie to you, because it moves when your traffic mix moves. Two numbers together do not:

type Order = { totalCents: number; items: number; createdAt: string };

export function weekly(orders: Order[]) {
  const n = orders.length;
  if (!n) return null;
  const revenue = orders.reduce((s, o) => s + o.totalCents, 0);
  return {
    orders: n,
    aov: revenue / n,
    // The one that actually attributes: did baskets get FULLER,
    // or did the expensive product simply sell more this week?
    unitsPerOrder: orders.reduce((s, o) => s + o.items, 0) / n,
  };
}

unitsPerOrder is the honest signal for these four mechanics, because all four work by adding items rather than by raising prices. If average order value rises and units per order does not, something else changed — a promotion, a channel, a seasonal product — and you are about to credit the wrong thing.

Watch the refund rate in the same window. A mechanic that raises the basket by pushing someone into a quantity they did not want shows up as returns four weeks later, and a return costs more than the margin the upsell earned.

What not to build

Three things that are commonly grouped with this list and do not belong in it:

  • A countdown on the discount. If the tier discount does not actually expire, a timer next to it is a fabricated deadline. There is a legitimate version of that component and it is narrow — see a countdown timer that is honest.
  • A pre-ticked complement. A tick the buyer did not make is not a sale, it is a refund with a delay. In the EU it also falls under the rules on unfair commercial practices.
  • A minimum order amount. It raises average order value by removing small orders, which is not the same thing as earning more money.

The four that work all share one property: the buyer would still have bought something if they had said no.

If you want a coding agent to produce these as real components rather than as a stepper and a progress bar, that is what uxgen does — it hands Claude the commerce mechanics as HTML you own, with no per-order fee. The open ones are in the commerce kit, MIT.

FAQ

How do you increase average order value without discounting?

Three of the four mechanics involve no discount at all. The free-shipping threshold trades shipping you already absorb for a larger basket, the named complement in the cart adds a small related item at full price, and the post-purchase addition sells after the money has moved. Only the quantity tier gives up margin per unit, and it more than recovers it on total margin per order.

Which upsell mechanic should I build first on a custom store?

The quantity tier on the product page. It acts on every order rather than on the subset that reaches a threshold, it asks the buyer nothing they were not already deciding, and it is the smallest of the four to build. Everything downstream inherits its effect, because a buyer who took a larger tier arrives at the cart already past the shipping threshold.

How do I know the upsell actually worked?

Track units per order alongside average order value, over the same window, and watch the refund rate for the four weeks after. All four mechanics work by adding items, so if average order value rises while units per order stays flat, something other than your components moved the number.

Do I need an app to run upsells on my store?

Only if your store is on a platform whose native surfaces you cannot reach, such as the post-purchase page on a hosted checkout. On a store you coded yourself, all four mechanics are components in your own repository with no recurring cost, no per-order fee and nothing to uninstall.

uxgen is a service of UXGen AI, LLC — 131 Continental Dr, Suite 305, Newark, DE 19713, United States.

© 2026 UXGen AI, LLC. All rights reserved.