Incorrect discount arithmetic produces wrong prices in every context where the formula runs — cart totals, checkout confirmations, order emails, and refund calculations. The canonical bug: subtracting percentOff as a dollar amount instead of a fraction (charging $100 - 20 = $80 when the intent is $100 × 0.80 = $80 — those happen to be equal, masking the bug until 10% off $50 yields $50 - 10 = $40 instead of $45). A fixed discount that allows negative final prices means a $200 off coupon on a $150 product produces a -$50 cart that Stripe rejects or, worse, creates a refund. ISO 25010:2011 maintainability is the external mapping — calculation logic must be testable and auditable.
Low because incorrect discount logic is detectable before release via manual testing, affects a bounded set of promotional transactions, and does not expose a security vector.
Implement all discount types in a single utility in src/lib/pricing.ts with explicit floor guards to prevent negative prices.
export const applyDiscount = (
basePrice: number,
discount: { type: 'percent' | 'fixed'; amount: number }
): number => {
if (discount.type === 'percent') {
return Math.max(0, basePrice * (1 - discount.amount / 100))
}
return Math.max(0, basePrice - discount.amount)
}
For stacked discounts, apply percentage discounts first, then fixed amounts — document the order explicitly in src/lib/pricing.ts so it doesn't become implicit tribal knowledge.
ID: ecommerce-catalog.variant-pricing.discount-logic
Severity: low
What to look for: Count all discount or promotion calculation functions in the codebase (search for discount, promo, coupon in src/lib/, src/utils/, and src/app/api/). For each function found, enumerate the discount types supported (percentage, fixed amount, BOGO, tiered). Test the logic with at least 2 sample values mentally to confirm correctness (e.g., 20% off $100 should yield $80, $5 off $100 should yield $95).
Pass criteria: Discount calculations are mathematically correct for all supported discount types. Percentage discounts reduce the price by the correct fraction, fixed discounts subtract the correct amount, and combined discounts apply in the correct order. Report even on pass: "X discount functions found, Y discount types supported."
Fail criteria: Discount calculations are incorrect (e.g., subtracts percentage as dollar amount, applies discount twice, allows negative final price).
Skip (N/A) when: No discount functionality exists in the project — confirmed by finding 0 discount-related functions, no coupon model, and no promotion logic in the codebase.
Cross-reference: For promotional compliance, the FTC Consumer Protection audit covers truthful advertising and discount disclosure.
Cross-reference: For coupon code security, the API Security audit covers input validation and rate limiting on promotion endpoints.
Cross-reference: For discount stacking logic, the Subscription Compliance audit covers pricing transparency in recurring charges.
Detail on fail: "Discount function in src/lib/pricing.ts subtracts percentage as a dollar amount instead of a fraction. 20% off $100 = $80 instead of $99.80" or "Fixed discount in src/utils/discount.ts can produce negative prices — no Math.max(0, ...) guard"
Remediation: Implement correct discount logic in src/lib/pricing.ts:
const percentDiscountedPrice = basePrice * (1 - percentOff / 100)
const fixedDiscountedPrice = Math.max(0, basePrice - fixedAmount)
const combinedPrice = Math.max(0, basePrice * (1 - percentOff / 100) - fixedAmount)