A coworker of mine was working on a TypeScript/JavaScript application that ran in a web browser. The application would display a dollar amount that was about to be charged to a customer's credit card. When the customer acknowledged the amount, the customer would be taken to a page hosted by the payment processor to actually perform the transaction. This seemed to be working correctly, but our QA tester found that certain dollar amounts, like $8.95, would show in our application as $8.95, but would be displayed as $8.94 on the payment processor's page.
The payment processors required monetary amounts to be sent in as cents, rather than dollars. For example, $54.12 would be sent as 5412. The developer had written something similar to the following to do this value conversion:
1 2 | const amount: number = 8.95; const paymentProcessorValue: number = amount * 100; |
The problem ended up being caused by the way JavaScript does math. JavaScript uses floating-point arithmetic to do calculations. In this particular case, 8.95 * 100 was not returning the expected 895, but instead was returning 894.9999999999999. The payment processor truncated the value at the decimal point, therefore it interpreted this value as $8.94, not $8.95.
The issue was corrected by rounding the value before sending it on to the payment processor.
1 2 | const amount: number = 8.95; const paymentProcessorValue: number = Math.round(amount * 100); |