i have integrated paypal adaptive payment system in a website, but i get an error while i checkout that if the amount upto 2 decimal places is not rounded off, the fractional amount could be lost. what is the solution to this? I am currently rounding off the amounts, but any idea how to get the fractional amount too?
-
What currency are you using that uses more than two digits to the right of the decimal point? US currency's smallest unit is one cent (0.01), and there is no smaller *fractional amount* than 1/100 of a dollar. The solution is proper rounding, so that fractional cents get rounded up (or down) appropriately. You can't very well tell a customer *Your cost is $11.125*, when that's not what's going to appear on their statement. – Ken White Oct 03 '17 at 17:34
2 Answers
You have to make sure that the amount you're sending to PayPal is rounded properly for the currency. This means that a US dollar amount would have at most 2 subunits (cents).
If using the adaptive pay ruby gems and still experiencing issues:
Another issue that I recently ran into with their ruby gems is that they use floats instead of decimals, which is a bad practice for monetary values. Floats are inaccurate. For example in ruby...
2.20 - 2.01 = 0.1900000000000004
If you're properly setting the amount's subunits when passing in the param to their build_pay
method and you're still getting the error...
If the fractional amount is rounded for currency conversion, funds could be lost
then the issue may very well be within their gem's use of float. Your logs will show this, and you can test it by using the amount 715.57
, which their gem sends to their api as 715.57000000001
because of their use of .to_f
in their paypal-sdk-core
gem.
To fix this, I monkey patched their Float
class in my rails app by adding this to my app, essentially casting it as a BigDecimal instead of a Float:
module PayPal::SDK::Core
module API
module DataTypes
module SimpleTypes
class Float < ::Float
def self.new(float)
# Floats are inccurate. BigDecimal is better.
# Ruby example: 2.20 - 2.01 = 0.1900000000000004
# To support currencies with up to 4 subunits, we round(4)
BigDecimal.new(float.to_f.round(4).to_s)
end
end
end
end
end
end
to my config/initializers/paypal.rb
. I can't say this is the most elegant solution, but it works. I created an issue on their repo too, and can hopefully hear back soon.
More info on float problems with currency:
Reference 1: https://stackoverflow.com/a/3730040/1109211
Reference 2: https://stackoverflow.com/a/3730249/1109211

- 153
- 2
- 7
If you are using PHP you can apply this solution. It is working in my case
$amount = 50.4854;
$roundedAmount = number_format(round($amount, 2), 2, '.', '');
Send rounded amount to PayPal, Hope it will work!

- 1
- 1