Grasshopper27
Grasshopper27

Reputation: 123

How to convert an integer to currency and display the correct cents

If @service.amount is equal to $28.95:

<p><%= number_to_currency(@service.amount) %></p>

is outputting $2895.00, not what I wrote above. After searching, I didn't find a solution.

@service.amount is an integer because Stripe only accepts integers.

Upvotes: -2

Views: 2032

Answers (2)

Stefan
Stefan

Reputation: 114168

Stripe stores values as cents. From the docs:

Zero-decimal currencies

All API requests expect amounts to be provided in a currency’s smallest unit. For example, to charge 10 USD, provide an amount value of 1000 (i.e., 1000 cents).

I assume that the API responses work alike.

To get the correct output, you have to divide the USD value by 100, e.g.:

<%= number_to_currency(@service.amount.fdiv(100)) %>

There's also the Money gem which might be a better alternative. It stores both, the value (as cents) and its currency, and comes with formatting:

require 'money'

money = Money.new(@service.amount, @service.currency)
#=> #<Money fractional:2895 currency:USD>

money.format
#=> "$28.95"

Upvotes: 3

edariedl
edariedl

Reputation: 3352

number_to_currency does not expect to get amount in cents. It thinks it is in dollars. What you have to do is convert amount in cents to dollars and then send it to number_to_currency method.

I don't know what object is @service but you should be be able to create another method called amount_in_dollars:

def amount_in_dollars
  amount / 100.to_d
end

and then use it in number to currency method:

<p><%= number_to_currency(@service.amount_in_dollars) %></p>

or you could divide it directly in the view (but I would prefer the first variant)

<p><%= number_to_currency(@service.amount / 100.to_d) %></p>

Upvotes: 1

Related Questions