Skip to content

Powered by Grav

Coming soon — KahunaCart is in final testing. Join the list and be first to know. Join the list

Money Conventions

This page describes how KahunaCart stores and calculates monetary amounts. It applies to every price, adjustment and transaction in the store.

KahunaCart uses vendored brick/money for calculation and BIGINT minor units for storage. Nothing monetary is ever a float.

Storage

  • Every monetary column is named *_minor and holds the amount in the currency's minor unit. 1999 is $19.99, and 500 is ¥500, because JPY has no minor unit and brick/money knows that.
  • Currency is stored once per order, in kahunacart_orders.currency as an ISO 4217 code. That order's items, adjustments and transactions are all in that currency.
  • Catalog prices are in the store currency from config.
  • Adjustment amount_minor is negative for discounts and positive for charges.
  • Transaction amounts are always positive. Direction comes from type, either purchase or refund.

Note

KahunaCart is single-currency. If multi-currency arrives, it will be a per-order currency chosen at cart creation, never mixed currencies within one order.

Calculation

  • All arithmetic happens on Brick\Money\Money values obtained through Grav\Plugin\KahunaCart\Money\Money::minor() and stored back with ::toMinor().
  • Raw integer math on minor units is allowed only for straight sums. Anything involving rates, division or allocation goes through brick/money.
  • Default rounding is HALF_UP, applied explicitly at defined points, such as after a percentage or tax computation. It is never applied implicitly mid-chain. The Money helper's methods encode these points, so do not call brick with other rounding modes.
  • Order-level amounts distributed across line items use Money::allocate(), which wraps brick's split() and guarantees no cent is created or lost. Order discounts and order-level tax back-allocation both use it.
  • Tax-inclusive prices back-calculate the included tax with Money::includedTax(). The result is stored as an adjustment with included = 1, so it appears on receipts without changing the total.
Why not hand-rolled integer arithmetic

Integer-cents arithmetic looks sufficient until you hit allocation (splitting $10.00 three ways), currency metadata (JPY has 0 decimals, BHD has 3) and compounding rate rounding. brick/money is MIT-licensed, actively maintained, PHP 8.2+, exact (it is built on brick/math), and widely deployed.

The one risk is a vendoring collision if another plugin ships a different brick/math version. The fix would be prefix-scoping the KahunaCart vendor namespace at build time.