{
  "id": 3601334,
  "title": "Designing a Discount-Validation API: Catching Stacked-Coupon Math Errors Before They Hit Production",
  "url": "https://urgent.news/2026/08/26/designing-a-discount-validation-api-catching-stacked-coupon-math",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-08-26T22:03:33.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/lizely/designing-a-discount-validation-api-catching-stacked-coupon-math-errors-before-they-hit-production-1lc2"
  },
  "original_language": "en",
  "account": "Stacked percentage discounts are not additive due to the nature of percentage calculations. A naive implementation that simply calculates price * (1 - (d1 + d2 + d3)) fails because successive discounts multiply the remaining price rather than the original price. This can lead to significant discrepancies when the customer sees the final amount. A better approach is to model discounts as a list of (factor, label) tuples, calculating the result in order and showing each step in the response for the front end to display.\n\nAnother common issue is order-dependence. While some discounts like BOGO or fixed-amount coupons may seem commutative, adding them to the mix can change the outcome. It's crucial to decide on the order at the data layer and document it in the API spec so the front-end team doesn't rearrange coupons client-side.\n\nThe core calculation involves computing final = price × Π (1 - d_i) − Σ fixed_j clamp(final, 0, price). This formula accounts for percentage discounts and fixed-amount coupons, with a clamp to ensure the final result is never negative. Failure to implement a clamp has resulted in bugs where customers received a credit they shouldn't have.\n\nRounding is another important consideration, especially given jurisdictional requirements for rounding half-away-from-zero to the nearest cent. Intermediate steps can be rounded differently as long as the consistency is documented, as auditors may ask about it. Using integer cents (or a Decimal type) and only converting to a display string at the boundary helps avoid floating-point arithmetic issues.\n\nTo ensure the discount calculator works correctly before shipping, a unit-test checklist should include testing single percentages, two and three stacked percentages, fixed amounts, negative-result clamping, zero-percent edge cases, full-discount edge cases, currency rounding, mutually exclusive coupons, and an unchanged price for an empty discount list. By systematically going through these test cases, you can uncover issues like additive math, premature rounding, or missing clamps, which are usually easy to fix once identified.",
  "summary": "If you've ever wired up a promo engine, you know the cheap-looking line items are where the bugs hide. A single product with three sequential percentage discounts — \"20% off, then 10% off, then a 15% loyalty coupon\" — is mathematically distinct from a flat 45% off, and most homegrown calculators get it wrong in the same three or four ways. This article walks through the engineering side of that…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}