Skip to content

fix(paypal): handle zero-decimal currencies properly during order creation - #29992

Open
misinierijon4-debug wants to merge 1 commit into
calcom:mainfrom
misinierijon4-debug:fix/issue-29983-paypal-zero-decimal-jpy
Open

fix(paypal): handle zero-decimal currencies properly during order creation#29992
misinierijon4-debug wants to merge 1 commit into
calcom:mainfrom
misinierijon4-debug:fix/issue-29983-paypal-zero-decimal-jpy

Conversation

@misinierijon4-debug

Copy link
Copy Markdown

Problem

When an event type is configured to accept PayPal payments in zero-decimal currencies such as Japanese Yen (JPY), the order creation path divides the stored amount by 100, causing PayPal to bill attendees only 1/100th of the configured price. For prices not divisible by 100 (e.g. ¥1,050), PayPal rejects the resulting decimal value and order creation fails.

Root cause

packages/app-store/paypal/lib/Paypal.ts in createOrder hardcodes (amount / 100).toString() for purchase unit values, assuming all currencies have 2 decimal places. Unlike standard currencies stored in minor units (e.g. USD cents), zero-decimal currencies like JPY are stored unscaled in integer units throughout the application.

Change

Updated createOrder in packages/app-store/paypal/lib/Paypal.ts to use convertFromSmallestToPresentableCurrencyUnit(amount, currency).toString() from @calcom/lib/currencyConversions. This ensures zero-decimal currencies (JPY, KRW, etc.) retain their full integer amount while minor-unit currencies (USD, EUR, etc.) continue to be divided by 100.

Proof

Test Red (Before Fix)

PS C:\Users\erijo\Downloads\claude\calcom> node --test packages/app-store/paypal/test_reproduce_issue_29983.mjs
Current value calculation in Paypal.ts: (amount / 100).toString()

Input: amount = 10000, currency = 'JPY'
Expected value sent to PayPal: '10000'
Actual value sent by Paypal.ts: '100'
▶ Paypal createOrder zero-decimal currency handling (Issue #29983)
  ✖ reproduces the bug in Paypal.ts createOrder when handling JPY (7.2918ms)
✖ Paypal createOrder zero-decimal currency handling (Issue #29983) (10.6252ms)
ℹ tests 1
ℹ suites 1
ℹ pass 0
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 443.7527

✖ failing tests:

test at packages\app-store\paypal\test_reproduce_issue_29983.mjs:12:3
✖ reproduces the bug in Paypal.ts createOrder when handling JPY (7.2918ms)
  AssertionError [ERR_ASSERTION]: BUG REPRODUCED: Paypal.ts sent '100' instead of '10000' for JPY ¥10000 (divided by 100!)
  
  '100' !== '10000'

Test Green (After Fix)

PS C:\Users\erijo\Downloads\claude\calcom> node --test packages/app-store/paypal/test_reproduce_issue_29983.mjs
JPY ¥10,000 -> Sent value: '10000'
JPY ¥1,050 -> Sent value: '1050'
USD $50.00 (stored 5000) -> Sent value: '50'
EUR €15.50 (stored 1550) -> Sent value: '15.5'
▶ Paypal createOrder zero-decimal currency handling (Issue #29983)
  ✔ Paypal.ts imports and uses convertFromSmallestToPresentableCurrencyUnit (3.9961ms)
  ✔ correctly formats JPY (zero-decimal currency) without dividing by 100 (1.8027ms)
  ✔ correctly formats non-hundred JPY prices without creating decimals (0.6343ms)
  ✔ correctly formats USD (minor unit currency) by dividing by 100 (0.4216ms)
  ✔ correctly formats EUR (minor unit currency with decimal part) (0.502ms)
  ✔ correctly formats other zero-decimal currencies (KRW, CLP, VND) (0.5542ms)
✔ Paypal createOrder zero-decimal currency handling (Issue #29983) (11.3723ms)
ℹ tests 6
ℹ suites 1
ℹ pass 6
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 388.7951

Reference

Fixes #29983
/claim 29983

Disclosure

This fix was written with AI assistance.

@github-actions github-actions Bot added the 🐛 bug Something isn't working label Aug 18, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Welcome to Cal.diy, @misinierijon4-debug! Thanks for opening this pull request.

A few things to keep in mind:

  • This is Cal.diy, not Cal.com. Cal.diy is a community-driven, fully open-source fork of Cal.com licensed under MIT. Your changes here will be part of Cal.diy — they will not be deployed to the Cal.com production app.
  • Please review our Contributing Guidelines if you haven't already.
  • Make sure your PR title follows the Conventional Commits format.

A maintainer will review your PR soon. Thanks for contributing!

@coderabbitai

coderabbitai Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b79ec326-d3bb-490b-b4e5-602210466c97

📥 Commits

Reviewing files that changed from the base of the PR and between 176037d and e892b9d.

📒 Files selected for processing (1)
  • packages/app-store/paypal/lib/Paypal.ts

Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

PayPal order creation now imports the shared convertFromSmallestToPresentableCurrencyUnit helper. It uses the requested currency during amount conversion instead of applying a fixed / 100 conversion.

Merge Risk: ⚪ Minimal · up to e892b

This change corrects PayPal order amounts for zero-decimal currencies while preserving existing formatting for currencies such as USD and EUR; no actionable merge-blocking risk remains beyond normal checks and review.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the PayPal fix for zero-decimal currencies during order creation.
Description check ✅ Passed The description explains the PayPal currency conversion bug, the root cause, the fix, and regression coverage.
Linked Issues check ✅ Passed The change replaces hardcoded division by 100 with shared currency conversion, addressing issue #29983 for zero-decimal and minor-unit currencies.
Out of Scope Changes check ✅ Passed The changes are limited to PayPal order-creation currency conversion and align with the linked issue objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 bug Something isn't working size/XS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug]: PayPal charges JPY bookings 1/100th of the configured price

2 participants