---
title: "Quantity-cap Discount Function"
summary: "A judgment-first walkthrough: when apps fail, how to split overflow to full price, and what to verify before you ship. Illustrative code — not production IP."
publishedAt: "2026-07-14"
status: published
series: "Shopify Functions"
episode: 3
duration: "12:40"
level: "Intermediate"
youtubeId: "dQw4w9WgXcQ"
prerequisites:
  - "Shopify Plus or Functions access"
  - "Node 20+ · Shopify CLI"
  - "Familiarity with cart lines"
  - "A staging shop (never prod first)"
chapters:
  - { title: "Why apps fail", at: "00:00" }
  - { title: "Scaffold the Function", at: "02:10" }
  - { title: "Split overflow lines", at: "05:40" }
  - { title: "Verify in cart", at: "08:15" }
  - { title: "Discovery checklist", at: "11:00" }
relatedNotes:
  - what-to-ask-before-a-function
relatedWorkHashes: []
contentKind: watch
---

## Scaffold the Discount Function

Start from Shopify CLI. Keep the Function tiny — CAP as a constant you can later
move to metafields once the mechanic is proven on staging.

```javascript
// src/run.js
const CAP = 3;

export function run(input) {
  const lines = input.cart.lines.filter((l) => l.quantity > 0);
  if (lines.length === 0) return { discounts: [] };
  return { discounts: lines.flatMap(capLine) };
}
```

## Split overflow to full price

When quantity exceeds CAP, discount only the capped units. Overflow becomes its
own line at full price — the mechanic apps kept getting wrong.

```javascript
// src/cap.js
function capLine(line) {
  if (line.quantity <= CAP) {
    return [{ targets: [{ cartLine: { id: line.id } }], value: { percentage: 20 } }];
  }
  // Only the first CAP units are discounted; the rest stay full price.
  return [
    {
      targets: [{ cartLine: { id: line.id, quantity: CAP } }],
      value: { percentage: 20 },
    },
  ];
}
```

## Verify edge cases before staging sign-off

Test mixed carts, gift lines, and CAP changes. If marketing can edit CAP
mid-campaign, put it in a metafield — don't redeploy for a number.

- `qty ≤ CAP` → single discounted line
- `qty > CAP` → split + full-price overflow
- gift / zero-price lines untouched
- B2B company location pricing still resolves
