camaraproject / CarrierBillingCheckOut

Repository to describe, develop, document and test the Carrier Billing Check Out API family
Apache License 2.0
9 stars 9 forks source link

Type representing money values #105

Closed rartych closed 7 months ago

rartych commented 9 months ago

Problem description Currently amounts of money are defined as:

        amount:
          type: number
          format: float
          multipleOf: 0.01

Swafgger docs indicates

multipleOf may be used with floating-point numbers, but in practice this can be unreliable due to the limited precision or floating point math.

Possible evolution

Storing amount values as long integers is a common best practice

Field Name OpenAPI type OpenAPI format Description
amount integer int64 Represented in "minor units"
currency string currency "Minor units" depend on the currency value.

Note: Minor units are specified according to ISO 4217 and can be found in this table.

Additional context

Recommendation in: https://github.com/team-monite/api-style-guide/blob/main/Guidelines.md#should-use-the-common-money-object

Storing amount values as long integers is a common best practice, adopted by API payment providers like Adyen and Stripe.

Most currencies have two decimals. Some currencies do not have decimals, and some have three decimals. For example:

PedroDiez commented 8 months ago

Have checked this internally. In Telefonica, billing/charging systems manage "decimals" in a natural way.

Providing amount as "integer" would have huge impacts in systems as it is needed to manage a conversion to identify the number of decimals to be considered. Usually merchants are aware of this kind of stuff in different countries and manage it.

Then our position is to keep current model. Would also like to know opinions from other participants.

Anyway, an enhancement is derived from your analysis @rartych. We need to address scenarios with 3 decimals.

So for amount, should be needed to be described as:

        amount:
          type: number
          format: float
          multipleOf: 0.001

float also includes integers so for currencies that do not consider decimals an integer can be signalled and Schema validation does cover it.

PedroDiez commented 8 months ago

25/10: Moving forward with

        amount:
          type: number
          format: float
          multipleOf: 0.001
PedroDiez commented 7 months ago

Closed as per PR#119 MERGED