Currency handling is consistent
Why it matters
Floating-point arithmetic on monetary amounts produces silent rounding errors — 0.1 + 0.2 is 0.30000000000000004 in JavaScript. When tax, discounts, or proration are calculated using float dollars instead of integer cents, the errors compound across transactions. CWE-681 (Incorrect Conversion Between Numeric Types) covers this, and ISO 25010 functional-correctness requires that calculations produce accurate results. Formatting currency with string concatenation ("$" + amount) produces locale-incorrect output (wrong decimal separators, missing grouping) and breaks for non-USD currencies.
Severity rationale
Low because floating-point rounding errors in typical SaaS pricing are small per transaction, but compound at scale and can produce incorrect invoice totals.
Remediation
Store all monetary amounts as integers in the smallest currency unit (cents for USD). Use Intl.NumberFormat for display and integer arithmetic for calculations.
// Store amounts as cents (integer)
const amountCents = 2999 // $29.99 — never store as 29.99
// Display with locale-aware formatting
const display = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
}).format(amountCents / 100) // "$29.99"
// Arithmetic stays in integer cents
const taxCents = Math.round(amountCents * 0.08) // 240 — not 2.392...
const totalCents = amountCents + taxCents // 3239 — exact
Stripe's API returns amounts in the smallest currency unit by default — work in those units end-to-end and only convert to display format at the UI layer.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Billing & Payments Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-681 — Incorrect Conversion Between Numeric Types
- iso-25010:2011 · functional-correctness — Functional Correctness — monetary arithmetic produces accurate results free of floating-point errors
Taxons
History
- 2026-04-18·v1.0.0·Initial import from saas-billing·automated