# Checkout Upsell

> Build the upsell that belongs in THIS cart, checkout or thank-you page — order bump, post-purchase one-click upsell, cart-drawer cross-sell, free-shipping threshold bar — deciding which one goes where from the merchant's product and basket, not from a template. Carries the placement table (product page vs cart vs checkout vs post-purchase), the pricing rule for a bump, the one-click rule for post-purchase, the "display only" rule for the shipping bar, and the consumer-law constraints that make a pre-ticked add-on refundable in the EU. Use for any cart drawer, checkout, order confirmation, thank-you page, one-click upsell, order bump, cross-sell, "frequently bought together", free shipping bar, average order value or AOV work, for Shopify checkout extensions, and whenever an agent is about to add a stepper, a carousel or a pre-ticked box to a cart.

- Skill: `kinerette/checkout-upsell` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add kinerette/checkout-upsell`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kinerette/checkout-upsell/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- License: MIT
- Author: kinerette (https://skillmd.com/u/kinerette)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/kinerette/checkout-upsell

---


# 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](https://eur-lex.europa.eu/eli/dir/2011/83/oj)
  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](https://eur-lex.europa.eu/eli/dir/2005/29/oj) 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`](https://github.com/kinerette/claude-code-store-design),
covers the product page.

Built by [uxgen](https://www.uxgen.ai). MIT.

