Checkout upsell
An upsell is not a component. It is a place and a moment: the same offer sells on the thank-you page and kills the sale in the checkout form. Generated storefronts get the component right and the place wrong, because the web has thousands of "upsell widgets" and almost nothing on where each one belongs.
This skill is the placing. Then the building.
Do this first
Read references/placement-table.md before adding anything to a cart.
Four places, four mechanics, one rule each. The table says which mechanic goes in which place for the merchant's product, and — more useful — which combinations are wrong on any product.
The short form:
| Place | The one mechanic that belongs there | What never goes there |
|---|---|---|
| Product page | quantity breaks (named tiers) | a bump, a carousel |
| Cart / drawer | free-shipping bar + one cross-sell | a second cross-sell, a modal |
| Checkout form | one order bump, above the totals | anything with more than one item |
| Post-purchase / thank-you | one-click upsell, already paid | a form, a re-entry of card details |
If you take one rule from this file
One offer per place. Never two.
Two offers in the same place is a catalogue, and a catalogue asks the buyer to compare, which is the thing the buyer had just finished doing. The measured pattern in DTC stores that grow the basket is one named item per surface, priced well below the basket, with one concrete reason.
When to use this skill
- Any cart drawer, cart page, checkout, order confirmation or thank-you page.
- The task mentions an order bump, a post-purchase upsell, a one-click upsell, a cross-sell, "frequently bought together", "complete the look", a free shipping bar, or AOV.
- A Shopify checkout extension or a post-purchase extension is being built.
- Someone says the cart "feels empty" or "we want to increase order value".
- An agent is about to put a quantity stepper, a product carousel, or a pre-ticked checkbox anywhere near a payment button.
The reference files
Load them as the task calls for them. Do not load all of them at once.
| File | Read it when |
|---|---|
references/placement-table.md |
Always, first. Which mechanic, which place, why |
references/order-bump.md |
Building the checkout bump: pricing, wording, position, the unchecked box |
references/post-purchase.md |
Building the one-click upsell after payment: what makes it one click |
references/cart-cross-sell.md |
The cart drawer: the single complement, the −15% chain, the shipping bar |
references/rules.md |
Before shipping anything with an add-on, a discount or a "free" |
The rules, condensed
Order bump. One item. One price. One concrete reason in one sentence ("Most people add the refill — it runs out first"). Sits above the order totals, inside the checkout form, styled as part of the form. The checkbox starts unchecked and there is no prop that can make it start checked. Priced at roughly 10–30% of the basket; a bump that costs as much as the basket is a second decision, not an add-on. Never a carousel. Never a screen the buyer has to dismiss to continue.
Post-purchase upsell. Shown after payment succeeded and before the thank-you page. It is one click because the payment method is already authorised — if the buyer has to re-enter anything, it is not a post-purchase upsell, it is a second checkout, and it converts like one. One item, a real price, a "No thanks" that is a plain link the same size as the accept button. One offer, or a decline followed by at most one more. The order the buyer just placed is never changed by declining.
Cart cross-sell. One complement, chosen by the product's logic, not by "customers also bought". A complement completes the use of the thing in the cart (the refill, the case, the second colour to share). Priced with a real chained discount if the shop can afford one — the observed pattern is the second item at −15%, the third at −15% again, each step shown in currency. Mono-product shop: offer the double only if doubling is logical, otherwise offer nothing. An invented complement puts something in the cart the buyer did not want and comes back as a return.
Free-shipping bar. The remaining amount in currency, never a bare percentage. Display only: the threshold and the remainder come from the same functions that charge shipping at checkout, never from a constant retyped in the component. Not in an empty cart. Never on a digital product.
Never fabricate proof. No generated review count, star average, "12 people are viewing", "only 3 left" or countdown seeded from the page load. Build the slot and leave it empty rather than fill it falsely.
Two constraints that are law, not preferences
- Never pre-tick an add-on. Article 22 of Directive 2011/83/EU requires express consent to any payment beyond the main obligation, and makes a payment inferred from a default the consumer had to reject refundable. Several commercial upsell apps ship pre-ticked as their factory default.
- Never call it "free" if it is not. "Free gift with purchase" is a gift only if the basket total does not move. Point 20 of Annex I of Directive 2005/29/EC lists describing a product as "free" when the consumer has to pay anything beyond the unavoidable cost of responding as a practice that is unfair in all circumstances.
Full reasoning, plus the UK and US equivalents, in references/rules.md.
What this skill does not do
It does not promise a lift. Below roughly forty thousand sessions per variant an A/B test cannot separate a real effect from noise, which is most stores. What these mechanics give you is the removal of a known omission — a cart with no complement, a checkout with no bump, a thank-you page that thanks and stops — which does not require a test to be worth doing.
It does not ship a component library. It teaches the placing and the rules. The judgement is the part that transfers; a pasted widget is the part that does not.
Why this exists
Asked on 25 August 2026 for a React component for "buy 2, save 15%", ChatGPT
returned a quantity stepper and cited no source; Perplexity returned a stepper
with min, max and step. Asked where to place an upsell on a product page,
ChatGPT cited nothing at all. There is no canonical, citable spec for where the
basket-growing mechanics go, so the models fall back to the median of what they
read, and the median of the web is a widget marketplace.
This skill is that spec for the cart, the checkout and the page after it. Its
sibling, store-design,
covers the product page.
Built by uxgen. MIT.