Mesrai
Back to blog
// essayTechnical Deep Dive

Discount Stacking Without Cap: The Free-Shipping Loop Bug

Real PR catch: discounts stacked multiplicatively with no cap — power users drop subtotal to 26%. Cap fix.

Mesrai TeamAugust 23, 20268 min read

A checkout flow stacking discounts multiplicatively without a cap. A user with 6 active 20% coupons would see their cart drop to ~26% of subtotal. Mesrai flagged the missing business rule.

The vulnerable diff

tscheckout/apply-discount.ts
// checkout/apply-discount.ts
function applyDiscounts(subtotal: number, discounts: Discount[]) {
  let result = subtotal;
  // BUG: multiplicative stacking with no cap
  for (const d of discounts) {
    result = result * (1 - d.percent / 100);
  }
  return result;
}

// Six 20% coupons stacked: 0.8^6 = 0.262 — user pays 26% of subtotal.

What is wrong

Discount stacking semantics are a business decision, not a math decision — but the code has to express it. The default 'just stack them' behavior leaks revenue when promotions overlap. The fix is to encode an explicit policy: a maximum total discount percentage, a one-coupon-per-order rule, or an additive (not multiplicative) cap. Each choice is a different business rule.

The attack

Symptom: revenue leak surfaces in margin reports weeks after a promotion ends. Hard to reconstruct because the bug is in the math, not the data.

textexploit
Marketing intended:
  - 'WELCOME20' for new users (20% off)
  - 'BIRTHDAY10' for monthly birthday users (10% off)
  - 'REFER15' for referrers (15% off)

User stacks all three: 0.8 * 0.9 * 0.85 = 0.612 → 38.8% off.
Marketing budgeted for 20% off at most.

Compound discounts surprise everyone — engineering, marketing, finance.

Mesrai's review comment

textreview-comment.txt
mesraipilot · Bot · reviewed 1 min ago

[mesrai] [code-review] [Logic] [Business-Rule] [medium]

Discounts stacked multiplicatively without a cap. Power users can
exceed intended discount.

Make the policy explicit. Options:

  // Hard cap at total discount percentage
  const MAX_DISCOUNT_PCT = 30;
  const totalPct = Math.min(MAX_DISCOUNT_PCT, discounts.reduce(
    (acc, d) => acc + d.percent, 0
  ));
  const total = subtotal * (1 - totalPct / 100);

  // Or: only the best single discount
  const best = Math.max(0, ...discounts.map(d => d.percent));
  const total = subtotal * (1 - best / 100);

  // Or: additive cap with priorities
  // Discounts ordered by priority; stack additively until cap hit.

Pick the business rule with product/marketing. Encode it in code +
unit test it with the stacked-discount edge cases.

The fix

tscheckout/apply-discount.ts (fixed)
// checkout/apply-discount.ts — fixed
const MAX_DISCOUNT_PCT = 30;

function applyDiscounts(subtotalPaise: number, discounts: Discount[]): number {
  // Additive percentages, capped
  const totalPct = Math.min(
    MAX_DISCOUNT_PCT,
    discounts.reduce((acc, d) => acc + d.percent, 0)
  );
  return Math.round(subtotalPaise * (10_000 - totalPct * 100) / 10_000);
}

Additive percentages, explicit cap, integer paise math. Test cases for: no discount, single discount, exactly-cap discount, over-cap discount.

Why human review missed it

Discount stacking edge cases are rarely scoped during initial implementation — promotions appear later and stack unintentionally. Mesrai catches discount-application loops without an explicit cap and asks for the business rule.

Related rules + further reading

Mesrai rule pack: logic/discount-stacking-cap — flags discount loops without cap.

Stripe Coupons doc § Stacking rules.

Common revenue-leak bug in subscription billing.

Takeaway

Discount stacking needs an explicit policy. Cap, single-best, additive — pick one. Mesrai catches the unrestricted stack.

// try

See it on your next PR.

Free for individuals. Install in two minutes. Mesrai reviews every commit.