Rounding rules
Every rounding mode with a worked example, plus what happens in currencies that have no decimal places.
Rounding is applied last, after the rate and markup, and always respects your store currency’s decimal places — two for USD or EUR, zero for JPY, three for KWD.
Modes in the free plugin
| Mode | Behaviour | 1234.567 becomes |
|---|---|---|
| No rounding | The calculated value, untouched | 1234.567 |
| Currency decimals | Rounded to the store currency’s decimal places | 1234.57 |
| Round up to a whole number | Always up | 1235 |
| Round down to a whole number | Always down | 1234 |
| Round to the nearest whole number | Standard rounding | 1235 |
| Charm pricing — ends in .99 | Up to the next value ending in .99 | 1234.99 |
How charm .99 actually behaves
The contract is that the result is never below the calculated price. Selling a penny below the anchored price is a margin loss on every single unit of every product priced at a round figure, and that is exactly the bug a naive implementation produces.
- 298.20 becomes 298.99 — up, as expected.
- 299.00 becomes 299.99, not 298.99. A naive
ceil(price) - 0.01would have gone down here. - A price that is already exactly x.99 stays at x.99.
In a currency with fewer than two decimal places, “.99” cannot be expressed at all. Rather than silently produce a price the store cannot represent, charm mode falls back to rounding up to a whole unit, which still honours the never-below contract.
Choosing a mode
- Currency decimals is the safe default. It produces honest, exact conversions.
- Round up to a whole number suits markets where prices with visible decimals look unfinished, and it never rounds against you.
- Charm .99 suits consumer retail where price psychology matters.
- Round down is the only mode that can round against your margin. Use it deliberately, and be aware it compounds with a thin markup.
- No rounding is mostly useful while testing, when you want to see the raw arithmetic.
Pro rounding modes
Pro adds charm endings of .9, .90 and .999, rounding to multiples of 5, 10, 50 or 100, and a configurable minimum increment. These are registered through a strategy registry rather than by extending the free plugin’s enum, because a PHP enum cannot be extended.
If Pro is deactivated while a Pro-only rounding mode is selected, the free plugin falls back to no rounding. Prices stay valid and no product is left unpriced — the number simply stops being charmed.