Giter Club home page Giter Club logo

Comments (5)

LostKobrakai avatar LostKobrakai commented on July 17, 2024 2

We could work on @kipcole9's suggestion of implementing a protocol and accept any Money lib that implements it. But how do we go about doing that?

Let's use ex_money or a protocol and track it's integration into Gringotts here.

You could do both. Use a protocol for the values sent to your public interface functions and convert those to money structs used internally.

from gringotts.

kipcole9 avatar kipcole9 commented on July 17, 2024 1

I think its important not to tie Gringotts to a single lib in any way. That would limit choices and potentially stifle innovation.

I support @LostKobrakai's suggestion. Protocol support at the public api level where money is being submitted to the gateway. For a return value from the gateway use your own Gingotts.Money.t type defined however you need as long as it has a currency code and a decimal amount. And make sure your Gingotts.Money.t type supports the Protocol :-)

from gringotts.

oyeb avatar oyeb commented on July 17, 2024 1

Context

  • In #71, the protocol defines just 2 methods: value and currency.
  • All money libs provide a to_string method that returns a string including the currency symbol/code.

Additions to the protocol

  • float_string and integer_string (or similarly named) methods because most gateways accept a pair of "amount-as-string" and "currency code"; and though it's easy to extract and format the currency, converting the Decimal amount into a "precision aware string" is non trivial (rounding issues).
    • Interested libs could perhaps provide this by super-charging their to_string:
      # Notice the automatic rounding
      price = Money.new(4.1234, :USD)
      Money.to_string(price, currency: false) #=> "4.12"
      Such a to_string will make implementation of float_string trivially simple.
    • integer_string is useful for gateways that require amount as integer (like cents instead of dollars)
      Examples:
      Gringotts.Money.float_string(price) #=> "4.12"
      Gringotts.Money.integer_string(price) #=> "412"
      Money.new(4.1234, :BHD)
      |> Gringotts.Money.integer_string #=> "4123"
      # the Bahraini dinar is divided into 1000 fils unlike the dollar
      # which is divided in 100 cents

from gringotts.

kipcole9 avatar kipcole9 commented on July 17, 2024 1

Looks good. I believe that the integer output option should be a separate function. Following this discussion I have implemented, for ex_money two functions, to_integer_exp/1 and from_integer/2

to_integer/1

# current ex_money version
iex> m = Money.new(:USD, "200.012356")
#Money<:USD, 200.012356>

# Returns {iso4217, integer, exponent, remainder}
iex> Money.to_integer_exp(m)
{:USD, 20001, -2, Money.new(:USD, 0.002356)}

The reason that this should be separate from to_string/1 and should also be part of the protocol is because the money libs should take care of the relevant rounding - this is not as straight forward as it seems since different currencies have different rounding rules. My current version also returns a remainder since after rounding a remainder my exists. That is not Gringotts concern however so I propose the protocol function be to_integer(Money.t) :: {ISO4217 :: String.t, amount :: integer, exponent, integer}. I think the exponent should be included because again, I don't think Gringotts should need to have domain knowledge to calculate that but I think its important as an integrity check on the interface.

from_integer/1

iex> Money.from_integer(20000, :USD)
#Money<:USD, 200.00>

iex> Money.from_integer(200, :JPY)
#Money<:JPY, 200>

I think that could be the same API for Gringotts, being from_integer(amount :: integer, currency :: String.t). Note that is the money libraries responsibility to determine the exponent for the currency type.

Its possible that the payment gateway always assumes that the exponent is -2 - it would be good to know if that is the case. If it is, then the exponent would have to be passed in from Gringotts as a third parameter.

As soon as you settle on a draft protocol I'll implement it in ex_money master so you can try it out.

from gringotts.

oyeb avatar oyeb commented on July 17, 2024

Moving further progress to #85
A separate integer output function does seem better. We are not adding a from_integer right now.

from gringotts.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.