Representing price in response and request


#1

How are you representing price amount in your APIs? I think most popular choices are string and number (in Python, unfortunately, it is converted to float by default - connexion framework). type: number, format: decimal is not supported yet I believe. What is the best practice for this?

In case of number, I guess there could be added some converter to convert number to decimal right after validation?

Strings I think are easier for handling, would be converted to decimal inside handler. But then there is missing validation -> price is a number, not a string obviously. (solved by custom validation?)

I’ve seen this related issue in OpenAPI. Does json:api have a suggestion here?


#2

Fun fact: Int was actually suggestion by Mark Ralphson, member of OpenAPI initiative.

Relevant texts to price in API


https://allegro-restapi-guideline.readthedocs.io/en/latest/Representation/#price-and-currency

Usages:

String
https://developer.paypal.com/docs/api/overview/#make-your-first-call
http://developers.payu.com/en/restapi.html


https://w3c.github.io/payment-request/

Number


there are more of course, but we should not decide based on which one is used the most.

I’d use {"type": "string", "format": "decimal"} with custom validation.


#3

Hi, @lucas03!

In my projects I’m storing money amounts in cents, so there is no need to use decimal.

type: "Service",
attributes: {
    name: "Design an API",
    price: {
        currencyCode: "USD",
        amount: 12345678
    }
}

I didn’t clearly understood why you want to declare "type": "string". If you want to have money amount in your relationships - then you should create own type of resource. Call it as you want and how it’s better describe your resource: Price, Money or whatever.

relationships: {
    price: {
        data: {
            type: "Price",
            id: "price-1"
        }
    }
}

#4

Hi and thanks for answer :slight_smile: I don’t wanna use strings, as I need to support multiple currencies with various precision.

I’ll create custom type, but I wanna avoid having it as number. As people often cast it to float, which is obviously bad for representing money. More on that in first three links I posted.


#5

Each currency has own precision, but any currency has their own “cents”, so you can store amount in it. The only problem with it: frontend application need to fetch collection of all supported currencies and get this precision from it, to know on what number they should divide money amount to receive dollars, euros, etc instead of cents, eurocents, etc.