@nhero points out in #1467886-76: PCI-DSS compliance using stripe.js that the assumption that charges should be multiplied by 100 is a USD assumption, and that when the currency format is set to something other than 2 decimal places all kinds of problems can result. @nhero provides a patch there, but I think it doesn't do enough.
Stripe requires charges for any currency to be "A positive integer in the smallest currency unit (e.g 100 cents to charge $1.00, or 1 to charge ¥1, a 0-decimal currency) representing how much to charge the card." (reference. They seem to imply that there are only two types of currency: 2-decimal currencies like the dollar and Euro, and zero-decimal currencies.
So I see these issues:
1. We shouldn't be using uc_currency_format() for preparing the amount - it makes no sense to rely on formatting when what we're really interested in is the multiplier to get from the provided amount to the absolute number of "smallest currency units".
2. We have to find out from *somewhere* what the smallest currency unit multiplier is.
I'm interested in potential approaches, and what problems are currently encountered.
Regardless, as of 2015-10-04, you have to use 2-digits as your setting for currency formatting because of the assumption currently used in calling uc_currency_format()
| Comment | File | Size | Author |
|---|---|---|---|
| #5 | stripe_must_charge_in-2580025-5.patch | 2.25 KB | ayesh |
| #4 | uc_stripe.zero_decimal_currencies_2580025_04.patch | 2.73 KB | rfay |
Comments
Comment #2
nhero commentedYes, we are using a zero-decimal currency which is how we discovered this issue.
Comment #3
rfayHere's my opinion:
- uc_stripe should add its own config item, uc_stripe_currency_mulitplier, set to either 100 or 1 at this point, with 100 the default, as it works for most currencies.
- When charging on stripe, we should multiply by that number.
Comment #4
rfayHere's the approach suggested in #3
Comment #5
ayesh commentedTested the patch, and worked well.
This would be more of a feature request, but is there any chance we can figure this out on our own?
https://support.stripe.com/questions/which-zero-decimal-currencies-does-...
Here is a list of currencies that need "1" for the setting. In Ubercart, we have the default currency already set and can be taken from
variable_get('uc_currency_code'). Attached patch checks if the default or given currency code is among the 15 Stripe-supported currencies that should be using the "1" setting. This approach is almost the same, except that we figure out the setting ourselves without having to ask it from the site admin.Just a suggestion though.
Comment #6
rfayI'm ok with this approach, but the $zero_decimal_currencies should be loaded from a Drupal variable, rather than in code so it can be adjusted without code changes (but IMO it does not need a UI to set it).
Thanks for the review!
The one concern and the reason I didn't go as far as this: Somebody dealing with zero-decimal currencies will *also* want to change the Drupal variable uc_currency_prec (on admin/store/settings/store), so by leaving this in the UI it's all in their control (but somewhat confusing).
However, I agree with this approach, as long as the zero-decimal currencies are loaded from a var.
Comment #7
squarecandy commentedBummer this patch is still not in uc_stripe in 2020. Still requires setting USD currency to two decimal places to work.