StripeInvalidRequestError "Invalid positive integer": the 19.99 you sent Stripe that Stripe can never accept
Problem
The first end-to-end payment test on a new integration, and the API rejects the amount outright:
StripeInvalidRequestError: Invalid positive integer: 19.99
at card charge: amounts must be sent in the smallest currency unitThe code reads exactly like the demo, the amount is a perfectly reasonable 19.99, and nothing in the error mentions where the decimal rule is documented.
Root cause
Stripe's amount parameter is an integer in the smallest currency unit — cents for USD/EUR, and (the part that bites people months later) units of 100 for JPY/KRW, which have no minor unit. 19.99 arrives as a float, fails integer validation, and the API returns StripeInvalidRequestError with a message that names the parameter but reads like a complaint about positivity.
The second-order bug is the "fix" people reach for first: Math.round(19.99 * 100) works for most values and silently produces 1989 instead of 1999 for values like 19.89 * 100 = 1988.9999999999998 — classic binary float rounding, shipping a real discount to every affected customer.
// amount comes from your pricing data as a string or Decimal, not a float
function toMinorUnits(amountStr, currency) {
const zeroDecimal = ['JPY', 'KRW', 'VND', 'CLP']; // currencies with no minor unit
… 13 more lines in the fix🔒 the fix — including 2 code blocks — is members-only. $1/mo unlocks everything.