Repository navigation
fix(payment): round to currency precision regardless of server locale - #17452
Conversation
ðĶ Changeset detectedLatest commit: 41552a3 The changes in this PR will be included in the next version bump. This PR includes changesets to release 83 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Thanks for the contribution! Initial automated review looks good. Verdict: Looks good for initial approval. Replaces the locale-dependent Checked: security (no user-controlled input in the changed path), performance (no query or loop changes), correctness, conventions, changeset ( Triggered by: new PR opened |
|
Thanks for the contribution! Initial automated review looks good. Verdict: Looks good for a final review by the team. Replaces the locale-sensitive Checked: security (no user-controlled input in this path), performance (synchronous calculation, no query changes), correctness, conventions, changeset (patch bump for Triggered by: new commit pushed |
Summary
What â The Payment Module now works out a currency's rounding precision without depending on the server's locale. This fixes rounding for zero-decimal currencies and for servers running under locales that use a comma as the decimal separator.
Why â
roundToCurrencyPrecisioncounted decimals by formatting a number withIntl.NumberFormatin the default locale and splitting the result on".". That breaks in two cases:"."at all.de-DEthe separator is",".In both cases the split threw, the catch kept full precision, and capture checks compared unrounded amounts. Valid captures were then rejected with "You cannot capture more than the authorized amount...", and full-capture detection was also affected. Only servers running
en-US-style locales with two-decimal currencies worked.How â
packages/modules/payment/src/services/payment-module.ts:177now readsresolvedOptions().maximumFractionDigitsfrom the formatter. That value comes from the currency's data, not the formatted string, so it doesn't depend on the locale. It gives 0 for JPY and 2 for EUR/USD under every locale. Unknown currencies still throw and keep full precision, as before.Testing â I added two tests to
packages/modules/payment/integration-tests/__tests__/services/payment-module/index.spec.ts:Intl.NumberFormatforced tode-DEBoth failed before the fix with the "cannot capture more than the authorized amount" error, and both pass after it. The full spec (68 tests) and the package unit tests pass.
Checklist
Additional Context
The module integration runner loads the payment module from
dist, and the package couldn't be rebuilt in this environment. So I ran the spec againstsrcby temporarily passingresolve: <package>/srctomoduleIntegrationTestRunner, then removed that change. CI builds before running integration tests, so the committed spec doesn't need it.Fixes #16974