When using the this module in combination with another module that modifies the payment amount (the taxes module from Ubercart or the VAT module for example) it sometimes doesn't work. It all depends on how you change the payment amount. It turns out that when you send a float with digits behind the comma you'll get weird behavior. No error messages, when forwarded to the Adyen checkout skin there are no options and a vague message.
What I've done to get around this is the following:
replace line 262 of uc_adyen.module: $payment_amount = $order->order_total*100;
with: $payment_amount = intval($order->order_total*100);
The payment amount needs to be changed to an int to fix it properly. I've got confirmation from Adyen that they expect an int and not a float there.
Comments
Comment #1
xibun commentedThis was fixed Dec 22. please use the dev version.
Comment #2
stevy99 commentedAwesome, thanks!
Comment #4
crystaldawn commentedThis fix was fixed incorrectly. It uses round(). But when dealing with money you always round UP no matter how small the decimal place is. round() needs to be replaced with ceil(). I also recommend using ceil in any/all other modules you create rather than round when dealing with money.
Comment #5
xibun commentedthanks for the review. actually after committing this patch I was thinking I should have gone with stevy99's suggestion and use intval to round down. there can be confusing edge cases where the customer is shown a certain amount let's say 19.99 in the shop but he would be charged 20.00 in the payment process. using your approach we would actually double those cases.
but I'm happy to learn more about your rounding UP rule. can you please provide more information?
Comment #6
crystaldawn commentedSure here's why. Its basically saving money rather than losing money. If you continuelly round down with 3.014 for example, you will eventually lose money because of the .014 adding up to a whole number. So, when dealing with money, no matter how small, you should always round up :) here are a couple financial websites to consider that kind of explain this idea in a different way but that gets the point across rather well:
http://www.ehow.com/how_2107845_save-money-rounding-up-payments.html
The trickyness comes in that you only round UP when it's in the 3rd decimal place. Here are some examples:
$3.01 == $3.01
$3.011 == $3.02
$3.019 == $3.02
Why? Because whenever you deal with money you want to make or save as much as possible. Therefore you always round UP when dealing with money. The most common example is a gas station. Consider the following:
Gas station 1 has a price of:
$2.789
And gas station 2 has a price of:
$2.781
Which one charges the most? Neither. They charge the same which is $2.79. You'll see this around town if you look close enough :) In some states using anything other than .009 is not legal, but in others there is no law against what number you use and you'll see oddball numbers like 0.001, 0.005, etc. Its simply a marketing ploy because in reality you pay the same no matter what the number says.
I've built many systems for banks, and I can tell you from experience, there isnt a single bank on the planet that will ever round DOWN. Even when it involves giving you money back believe it or not (mainly because by law they cant, otherwise they would round up when they are receiving and down when giving). Thus, whenever dealing with money it's always best to be on the safe side and round up. Otherwise you might get sued for jipping someone. It's a good debate. Personally, I like to round up when receiving and down when giving but that can be dangerous if someone caught on :P
Comment #7
xibun commentedFor sure we need to continue the checkout process with the same price from beginning to the end. At least in Europe we cannot tell the customer that the total price is 9.99 (let's say with the internal precision of five digits it is actually 9.99001) and then send the customer to the payment provider (Adyen in the case of this module) and ask him to settle 10.00.
So the solution is to make sure the formatting of the total price to the customer during the checkout process is the same as the formatting used to communicate that same total price to the payment provider. With the additional requirement from Adyen to send the value as "minor units" (= multiplied by 100 and without decimal separator).
The price handler of ubercart (uc_price.inc):
Where as uc_adyen.module currently uses (line 290):
Note: this can deliver inconsisten numbers in case the store settings for "Number of decimal places:" is not set to "2".
The following code will make the behaviour between checkout and payment consistant:
And finally an additional security in case someone has the idea to hack the system and set more than 2 decimals in his shop:
commited to dev.