Open lukeholder opened 7 years ago
Sorry - only just spotted this.
The original commits came from issues with different decimal accuracies being set for different PHP installations, meaning a simple cast to (string)
gave different results on different installations. For example, some sites may give 1.66 and others may give 1.659999999997 The sprintf()
was meant to bypass that and make sure the accuracy (decimal digits to which a string representation of a float is rounded to) was the same for all installs.
Of course, nothing should ever go via a float in the first place, but we are stuck with it as legacy (for Omnipay 2.x at least).
What do you suggest for 3.x?
Not sure. I've always delegated money amounts to popular libraries with the assumption that they know how to handle this type of stuff better than me.
Well, in principle, we shouldn't touch the given value in most cases, unless we need to convert to integers at all.
In this case, we seem te be making a wrong decimal count, by casting it to max 8 decimals, see https://github.com/thephpleague/omnipay-common/pull/150
Would the fix using number_format
and removing insignificant zeros work?
Yes, it should do. An rtrim($string, '0')
should remove the trailing zeros, which surprisingly the PHP documentation does not explicitly state are added. It also doesn't mention the number is rounded.
Only thing I'm concerned about is the 'magic' 8 number. Is it good for everyone? Should it be number of decimals + 2? Should it depend on precision?
And should we throw an error at all? Downside of rounding is that it will depend on user input, so could fail depending on user input, right?
Hello,
Is there a work around for this issue? Thank you.
Using the Đồng (VND) currency, which has zero decimal places (zero minor units), returns an exception: "Amount precision is too high for currency." inside the
->getAmount()
method.I believe this commit is causing the error:
https://github.com/thephpleague/omnipay-common/pull/70/commits/529b18fe6b3196b4606b28548cb97ee913eaa914
The relevant line of code changed in the above commit is:
with
$amount
of VND 103500000, (anint
of 103500000) returns6
as the$decimal_count
, which is obviously incorrect. This is due to the result ofsprintf('%.8g', $amount)
being41035000001.035e+8
which has 6 chars to the right of the decimal.After restoring the original line:
with
$amount
of VND 103500000, (anint
of 103500000) returns0
as the$decimal_count
, which is the correct number of decimal places, and the transaction succeeds.I don't quite understand the rationale for the above commit, hoping that experienced omnipay minds can assist.
/cc @judgej
Example 1:
results in:
Example 2:
results in: