{"id":"discount-stack-apply","version":"1.0.0","description":"Apply an ordered stack of percent and fixed-amount discounts to a price, rounding each step or only at the end.","supported_operations":["stack 20% then 5% then 10% discount on 100","what is 10% off then another 5% off","apply a coupon of 5 euros after a 15 percent sale","chain discount calculator net price","single equivalent discount of successive discounts","total discount after several promotions","apply discounts one after another rounding each step to cents","effective discount percentage of a discount stack"],"unsupported_operations":["a single percentage of a number (use percent-compute)","tiered or volume pricing by quantity","promotion eligibility, coupon codes or usage limits","tax on the discounted price"],"semantics":["Inputs: price (non-negative decimal, a multiple of the minor unit by value), discounts (1..50 objects {kind, value} applied in array order), exactly one of currency (active ISO 4217 code) or scale (0..18), rounding (required), round_each_step (required boolean) and floor_at_zero (optional boolean, default true). kind \"percent\" takes value 0..100; kind \"amount\" takes a non-negative money value that is a multiple of the minor unit.","Chain: p0 = price; each step takes a raw discount d = running price x value/100 (percent, applied to the RUNNING price, so 10% then 5% is 14.5% off, not 15%) or d = value (amount), and p = previous - d.","round_each_step true: each d is rounded once to the scale with the mode before it is subtracted, so every running price has exactly scale fraction digits and later percentages apply to the rounded price. round_each_step false: no intermediate rounding (exact rational running price), final_price is rounded once; each step discount and price_after are rounded independently for display and need not add up to final_price.","floor_at_zero true: when a step would make the running price negative it is set to 0, clamped becomes true and that step discount is reduced to what was actually applied; later steps start from 0 (a price landing exactly on 0 does not set clamped). false: the price may go negative, clamped stays false, and a percent step on a negative price adds.","total_discount = price - final_price. effective_percent = total_discount x 100 / price rounded to 6 fraction digits with the same mode, \"0.000000\" when price is 0. Steps echo kind; value is the canonical decimal for percent (\"10.0\" gives \"10\") and the fixed-scale string for amount.","The ten rounding modes: half_even, half_up (ties away from zero), half_down, half_ceiling, half_floor, up, down, ceiling, floor, and unnecessary (any inexact rounding, including step values and effective_percent, is not_computable, reason rounding_necessary). Outputs never contain \"-0\".","Examples: 100.00 with 20%, 5%, 10% gives 80.00, 76.00, 68.40 (total 31.60, effective 31.600000); 100.00 with 10% then 5% gives 85.50 (effective 14.500000). An empty discounts array is invalid_input, more than 50 is limit_exceeded (checked before the elements), a percent above 100 is invalid_input, and a decimal string over 62 characters is limit_exceeded.","Data is the pinned ISO 4217 snapshot named by data_version; no clock, locale or network.","Disclaimer: arithmetic calculation only; not financial, tax, legal, or investment advice."],"limits":{"max_decimal_chars":62,"max_decimal_digits":60,"max_fraction_digits":40,"max_scale":18,"max_discounts":50},"pricing":{"status":"unpriced","charge_usd":null},"input_schema":{"type":"object","additionalProperties":false,"required":["price","discounts","rounding","round_each_step"],"properties":{"price":{"type":"string","minLength":1,"maxLength":62,"pattern":"^(0|[1-9][0-9]*)(\\.[0-9]+)?$","description":"Starting price, non-negative; at most the currency/scale precision by value."},"discounts":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"object","additionalProperties":false,"required":["kind","value"],"properties":{"kind":{"type":"string","enum":["percent","amount"]},"value":{"type":"string","minLength":1,"maxLength":62,"pattern":"^(0|[1-9][0-9]*)(\\.[0-9]+)?$","description":"percent: 0 to 100 (10 means 10%); amount: a money amount at most the scale precision by value."}}},"description":"Discounts applied in array order, each to the running price."},"currency":{"type":"string","minLength":3,"maxLength":3,"pattern":"^[A-Za-z]{3}$","description":"Active ISO 4217 alphabetic code with a minor unit (case-insensitive). Give exactly one of currency or scale."},"scale":{"type":"integer","minimum":0,"maximum":18,"description":"Fraction digits for non-ISO units. Give exactly one of currency or scale."},"rounding":{"type":"string","enum":["half_even","half_up","half_down","half_ceiling","half_floor","up","down","ceiling","floor","unnecessary"]},"round_each_step":{"type":"boolean","description":"true: round every discount to the scale and carry the rounded price; false: exact arithmetic through the whole chain, one rounding at the end."},"floor_at_zero":{"type":"boolean","default":true,"description":"Clamp the running price at 0 (default true)."}}},"output_schema":{"type":"object","additionalProperties":false,"required":["final_price","total_discount","effective_percent","steps","clamped","currency","scale","data_version"],"properties":{"final_price":{"type":"string","minLength":1,"maxLength":400,"pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","description":"Price after all discounts, fixed scale (negative only when floor_at_zero is false)."},"total_discount":{"type":"string","minLength":1,"maxLength":400,"pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","description":"price - final_price, exact."},"effective_percent":{"type":"string","minLength":1,"maxLength":400,"pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","description":"total_discount x 100 / price rounded to 6 fraction digits with the same rounding mode; \"0.000000\" when price is 0."},"steps":{"type":"array","minItems":1,"maxItems":50,"items":{"type":"object","additionalProperties":false,"required":["kind","value","discount","price_after"],"properties":{"kind":{"type":"string","enum":["percent","amount"]},"value":{"type":"string","minLength":1,"maxLength":400,"pattern":"^(0|[1-9][0-9]*)(\\.[0-9]+)?$","description":"percent: canonical decimal; amount: fixed scale."},"discount":{"type":"string","minLength":1,"maxLength":400,"pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","description":"Discount actually applied at this step (reduced when clamped), fixed scale."},"price_after":{"type":"string","minLength":1,"maxLength":400,"pattern":"^-?(0|[1-9][0-9]*)(\\.[0-9]+)?$","description":"Running price after this step, fixed scale."}}}},"clamped":{"type":"boolean"},"currency":{"type":["string","null"],"pattern":"^[A-Z]{3}$"},"scale":{"type":"integer","minimum":0,"maximum":18},"data_version":{"type":"string","const":"iso4217-datasets-7cdc784-2026-07-27"}}},"examples":[{"input":{"price":"100.00","discounts":[{"kind":"percent","value":"20"},{"kind":"percent","value":"5"},{"kind":"percent","value":"10"}],"currency":"USD","rounding":"half_up","round_each_step":true},"output":{"final_price":"68.40","total_discount":"31.60","effective_percent":"31.600000","steps":[{"kind":"percent","value":"20","discount":"20.00","price_after":"80.00"},{"kind":"percent","value":"5","discount":"4.00","price_after":"76.00"},{"kind":"percent","value":"10","discount":"7.60","price_after":"68.40"}],"clamped":false,"currency":"USD","scale":2,"data_version":"iso4217-datasets-7cdc784-2026-07-27"}},{"input":{"price":"10.00","discounts":[{"kind":"percent","value":"33.33"},{"kind":"amount","value":"3.33"}],"currency":"USD","rounding":"half_up","round_each_step":true},"output":{"final_price":"3.34","total_discount":"6.66","effective_percent":"66.600000","steps":[{"kind":"percent","value":"33.33","discount":"3.33","price_after":"6.67"},{"kind":"amount","value":"3.33","discount":"3.33","price_after":"3.34"}],"clamped":false,"currency":"USD","scale":2,"data_version":"iso4217-datasets-7cdc784-2026-07-27"}},{"input":{"price":"19.99","discounts":[{"kind":"percent","value":"15"},{"kind":"amount","value":"5.00"}],"currency":"EUR","rounding":"half_even","round_each_step":false},"output":{"final_price":"11.99","total_discount":"8.00","effective_percent":"40.020010","steps":[{"kind":"percent","value":"15","discount":"3.00","price_after":"16.99"},{"kind":"amount","value":"5.00","discount":"5.00","price_after":"11.99"}],"clamped":false,"currency":"EUR","scale":2,"data_version":"iso4217-datasets-7cdc784-2026-07-27"}}],"execute_url":"/v1/tools/discount-stack-apply/versions/1.0.0/execute"}