New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wrong charges on Stripe when using three digits subunit. #3725
Comments
@coorasse I'm not very familiar with this aspect of Solidus so I may be wrong, but I suspect the problem stems from the Can you clarify why you set that value to 1000? Perhaps there's a better way to achieve the same goal. |
We configured it like that because the shop administrator wants to set prices using 3 digits. |
@coorasse do you know the business requirement behind that choice? As far as I can see, for a product to cost 60.203 CHF doesn't mean anything to a customer if the smallest unit is 0.01 CHF. In fact, look at what happens with your fix: cents = 60203 # 60.203 CHF
subunit_to_unit = 1000
((cents / subunit_to_unit.to_f) * 100).to_i # => 6020 (60.20 CHF) This means that, even though the price of the product is 60.203 CHF, you're charging the customer 60.20 CHF (which, off the top of my head, may also cause accounting problems in the long run). I think that's the root of the problem here. Increasing If you could share a bit behind why you need such precision in the prices, we can probably find another solution. |
The client needs to set them with three digits. I cannot share too much information, but since the amounts bought are high, it really makes a difference for them to also be able to change the third digit. I can think about the gas price for example. Next to that, in this business case, we have also the option So the example you reported, is absolutely true in general, but it does not affect us because you cannot have a total of That was also my doubt: can we change it in the Payment model? Is there a case where the payment needs to be with cents precision? (so Still, at the moment, if you configure Solidus with any currency which has more than two digits for cents, Stripe charges are wrong. https://github.com/RubyMoney/money/blob/master/config/currency_iso.json#L223 |
Got it, the use case makes sense! With that said, I don't know if this is a general issue: I think if you create a Stripe charge in a currency that has more than two digits for cents, Stripe will compute the final amount correctly. For instance, I expect that a charge with In your specific situation, one problem I see is that Solidus may not mark the order as paid if the order total is smaller than the payment total because of the rounding that takes place in your custom Have you tried the Keep me posted on how it goes! |
@coorasse with Payment Intents at the moment the number if digits is hardcoded, see https://github.com/solidusio/solidus_stripe/blob/master/app/controllers/solidus_stripe/intents_controller.rb#L54. I guess this may not a problem for your specific scenario, as you said that the order will be charged up to 2 decimals anyways, but it may need to be addressed for other situations. |
@spaghetticode yeah, I think we need to fix that to use |
Thanks for the hint @aldesantis! Here are my findings so far:
So, to conclude, I think:
Thanks for the help so far! |
@coorasse thanks for the tests, I think the issues you found should be addressed — I'm pretty sure you're not the only store needing greater-than-usual precision for product prices. Would you have some time to submit your patches as PRs to the core? If not, I can also try to find some time this week! |
If it is not urgent, yes, I'd be glad to open a PR. Not this week, though. 👍 |
@coorasse I think this might be fixed by the release of |
In our system the prices are defined with three digits subunit. and the charges on Stripe are 10 times higher.
Solidus Version:
2.10.0
To Reproduce
Our Money configuration has the following:
to override the default behaviour.
Given an amount of
60.20 CHF
, when a Payment is captured or authorized (seesolidus/core/app/models/spree/payment/processing.rb
Line 51 in 66af3b6
solidus/core/app/models/spree/payment/processing.rb
Line 174 in 66af3b6
cents
is called which returns60200
instead of the expected6020
, necessary for the Stripe charge.Additional context
Our current patch consists of:
money.two_digits_cents
instead ofmoney.money.cents
.I'd love to open a PR with a fix, but I am not sure if this approach is correct. If you confirm me that it is, I'll proceed with a PR.
The text was updated successfully, but these errors were encountered: