Fixed an issue where payment amounts were incorrect due to rounding errors #25
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This pull request fixes an issue where amounts were being calculated incorrectly due to the way that PHP handles casting floats to integers. The problem code exists both for calculating the amount that is to be paid and when validating that the paid amount matches the expected amount.
For example, the payment total is calculated using
$amount = (int) ((float) SubjectReader::readAmount($buildSubject) * 100);
and let's use1268.10
as the return value ofSubjectReader::readAmount($buildSubject)
. Evaluating(int) ((float) 1268.10 * 100)
returns the resultint(126809)
which is one cent less than the actual order total.Out of curiosity, I ran some basic tests to see how often this might occur, and for order totals ranging from $0.01 to $100,000.00 it occurred 587,200 times (PHP 7.4.3).
The fix was just to round the value prior to casting it to an integer, although I have left this pull request as a draft for now because that is not necessarily the ideal solution.
You may or may not want to implement an alternative solution which utilises PHP's arbitrary precision math functions, or perhaps something purpose built for handling money such as https://github.com/moneyphp/money.