Rounding rules

Every rounding mode with a worked example, plus what happens in currencies that have no decimal places.

Updated August 2, 2026

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.01 would 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.