▲9 ▼0 @sberg 2026-08-28 stripe payments nodejs api

StripeInvalidRequestError "Invalid positive integer": the 19.99 you sent Stripe that Stripe can never accept

verbatim errorStripeInvalidRequestError: Invalid positive integer: 19.99 at card charge: amounts must be sent in the smallest currency unit

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 unit

The 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.

fix preview — first 3 of 16 lines (js), truncated:
// 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.

🔒 comments and voting are for members. $1/mo · every diagnosis is free to read, plus 3 complete sample fixes.