There is an issue with charged amounts in currencies without fractions (e.g. JPY) being divided by 100, which happens here: https://github.com/activemerchant/active_merchant/blob/db0e8d4f042b58aaff4af9fefef232f8e7528b8d/lib/active_merchant/billing/gateway.rb#L279
Perhaps override this method: https://github.com/solidusio/solidus/blob/e878076f2ed670d07654ab6293a16588743f2fa6/core/app/models/spree/payment.rb#L74
Error on Stripe API with fake card in testing mode:

Summary
I’m using the V1 api for a store in Japanese (JPY currency). Amounts are losing two zeros before being sent to the Stripe/Charges API.
Concerned Gems:
gem 'solidus', '~> 3.1'
gem 'solidus_stripe', 4.3'
Config:
config.static_model_preferences.add(
Spree::PaymentMethod::StripeCreditCard,
<img width="1478" alt="image" src="https://user-images.githubusercontent.com/7152249/205527744-9e2638e4-1ea4-4034-abbd-579032fa194f.png">
'stripe_env_credentials',
secret_key: ENV['STRIPE_SECRET_KEY'],
publishable_key: ENV['STRIPE_PUBLISHABLE_KEY'],
stripe_country: 'JP',
v3_elements: false,
v3_intents: false
)
My Research:
The auth trigger happens here (called by the state machine)
Sent to the gateway here
Money is calculated here
It goes through Monetize / RubyMoney using the 'cents' method. That flows through to here
This can be seen in practice with something like this:
order = Spree::Order.find('ORDER NUMBER HERE')
amount = order.payments.first.amount
currency = order.currency
Spree::Money.new(amount, {currency: currency})
=> #<Spree::Money:0x000000013b0d9f58 @money=#, @options={:sign_before_symbol=>true, :currency=>"JPY"}>
Spree::Money.new(amount, {currency: currency}).money.cents
=> 14000
All looks good so far…
This is then processed by the gateway here
Turned into a post for the Stripe API starting here
The amount for the post is calculated here
The amount is localized here
We can see that JPY is both in the payment (if you interrupt the authorization process to debug, the currency and country and correctly applied), so ‘JPY’ triggers currencies without fractions, which are specified here.
This all posts to the /charges/ path of the Stripe API
So, I think the amount is being converted to a float, then divided by 100, and then plugged into the api post. For example I have a product that has tax and shipping included that comes to ¥3200. At checkout in dev using a test api key, when going from confirm to complete (as authorize gets called), it’s giving an error that the amount is too low to be charged—¥32.
I first brought this up on Slack, and was encouraged to give it a go myself.
I'm still working on trying to fix it myself, but it's proving to be pretty stubborn (almost the same text as here).
There is an issue with charged amounts in currencies without fractions (e.g. JPY) being divided by 100, which happens here: https://github.com/activemerchant/active_merchant/blob/db0e8d4f042b58aaff4af9fefef232f8e7528b8d/lib/active_merchant/billing/gateway.rb#L279
Perhaps override this method: https://github.com/solidusio/solidus/blob/e878076f2ed670d07654ab6293a16588743f2fa6/core/app/models/spree/payment.rb#L74
Error on Stripe API with fake card in testing mode:

Summary
I’m using the V1 api for a store in Japanese (JPY currency). Amounts are losing two zeros before being sent to the Stripe/Charges API.
Concerned Gems:
Config:
My Research:
The auth trigger happens here (called by the state machine)
Sent to the gateway here
Money is calculated here
It goes through Monetize / RubyMoney using the 'cents' method. That flows through to here
This can be seen in practice with something like this:
order = Spree::Order.find('ORDER NUMBER HERE')
amount = order.payments.first.amount
currency = order.currency
Spree::Money.new(amount, {currency: currency})
=> #<Spree::Money:0x000000013b0d9f58 @money=#, @options={:sign_before_symbol=>true, :currency=>"JPY"}>
Spree::Money.new(amount, {currency: currency}).money.cents => 14000
All looks good so far…
This is then processed by the gateway here
Turned into a post for the Stripe API starting here
The amount for the post is calculated here
The amount is localized here
We can see that JPY is both in the payment (if you interrupt the authorization process to debug, the currency and country and correctly applied), so ‘JPY’ triggers currencies without fractions, which are specified here.
This all posts to the /charges/ path of the Stripe API
So, I think the amount is being converted to a float, then divided by 100, and then plugged into the api post. For example I have a product that has tax and shipping included that comes to ¥3200. At checkout in dev using a test api key, when going from confirm to complete (as authorize gets called), it’s giving an error that the amount is too low to be charged—¥32.
I first brought this up on Slack, and was encouraged to give it a go myself.
I'm still working on trying to fix it myself, but it's proving to be pretty stubborn (almost the same text as here).