paytrail / api-documentation

Paytrail Payment API documentation
MIT License
6 stars 11 forks source link

Preparation for the future: non-integer VAT #28

Closed mikkorantalainen closed 9 months ago

mikkorantalainen commented 2 years ago

Describe the bug

According to the documentation at https://docs.paytrail.com/#/?id=item the vatPercentage must be an integer and it's a required value. Currently all the possible VAT values in Finland are integers but many european countries are already using values such as 13.5%. How could this value be encoded for an item if needed in the future?

Expected behaviour

The field vatPercentage should be either a floating point number or an fixed point integer with suitable multiplier (e.g. 100x).

Actual behaviour

Field vatPercentage must be an integer even though there's pretty high probability that non-integer values are needed to match legislation in future.

Additional context

It's too late to redeclare field vatPercentage as a number with predefined integer multiplier.

One possible option to fix the already existing API would be to redeclare the vatPercentage as a floating point number – any existing callers should be automatically compatible with it because integer value is a special case for a floating point number. JSON floating point numbers should have enough accuracy to correctly transmit the correct VAT percentage in all cases.

Another possible way forward would be to introduce e.g. vatPercentagex100 where VAT percentage would be specified with multiplier 100. If this field is used, the vatPercentage should not be defined in the request.

mikkorantalainen commented 2 years ago

Also note that if you accept floating point number, you must differentiate in JSON syntax between ...,"vatPercentage":13.5,... and ...,"vatPercentage":"13.5",... in the spec. Using the string syntax would allow differentiating from the current usage where the value is JSON integer.

mattijv commented 5 months ago

Should this perhaps be reopened, since it now seems necessary?

terotests commented 5 months ago

Suggestion: add new optional field vatPercentageDecimalPart with range 0-99

jfrojd-paytrail commented 5 months ago

Thank you for the comments and suggestions. We have added this to our internal backlog and will publish the changes to the documentation once the development is complete.

mikkorantalainen commented 5 months ago

Maybe allow sending vatPercentageDenominator which has default value 1 but caller could set it to 100 and then set vatPercentage to 2550 to signal 25.5 %?

Allowing custom denominator would automatically fully support weird future political decisions such as having tax rate set to 24⅔ %, too. For that, you could set vatPercentage to 74 and vatPercentageDenominator to 3.

mattijv commented 5 months ago

Maybe allow sending vatPercentageDenominator which has default value 1 but caller could set it to 100 and then set vatPercentage to 2550 to signal 25.5 %?

Allow custom denominator would automatically fully support weird future political decisions such as having tax rate set to 24⅔ %, too. For that, you could set vatPercentage to 74 and vatPercentageDenominator to 3.

My only concern with this scheme is that it only allows for tax rates that are easily represented by rational numbers. There's a risk that future legislation introduces tax percentages (say π%) that require an unfeasibly large numerator and/or denominator to achieve the desired accuracy.

Maybe we could utilize something like continued fractions which are known to be good at approximating real numbers, and most "famous" - and therefore more likely to end up as a VAT percentage - real numbers have a matching continued fraction sequence in the Online Encyclopedia of Integer Sequences (and new ones can be added). So we can simply introduce a new integer field vatPercentageApproximatingContinuedFractionEntryInOEIS which can be used to look up the matching continued fraction terms to calculate the VAT to whatever accuracy is needed. For values for which a finite continued fraction is easy to construct ($255/10$), we could send the terms (in the format ${\displaystyle [i,a{1},a{2},\ldots ]}$) using a new integer array field.

This is also backwards compatible because we can still use the old field for those VAT percentages which are conveniently integers, and use the new fields for any tricky ones.

Why go for something complicated when a simple solution exist!

JanMkl commented 5 months ago

I think a simple solution would be to change representation of the vatPercentage field into percentage basis points meaning that 1% equals 100 basis points. Then the range of the field would 0...10000. This way the interface would support accuracy of 0,01% and still would be quite simple to implement as you don't need to go through all the code and change the types expected.

If backwards compatibility is to be maintained then a new optional field could be defined that tells whether the vatPercentage value is represented in percentage or in basis points. The default for this optional field would be percentage this way old interfaces doesn't require immediate update in those cases where we don't have decimals on the vat percentage.

mikkorantalainen commented 4 months ago

@jfrojd-paytrail: Any progress on this issue? At least the current documentation still seems to specify vatPercentage as integer : https://docs.paytrail.com/#/?id=item

vatPercentage integer (required) (default: 24) VAT percentage.

mikkorantalainen commented 3 months ago

Could you guys reopen this issue because this is clearly not yet handled? The new law takes action in September 2024 and you still haven't told us how your API is supposed to work by then!

mikkorantalainen commented 1 month ago

It seems that Paytrail has finally updated the documentation: https://docs.paytrail.com/#/?id=item (you have to load the URL twice or the page will not scroll to correct position – the page probably has some racy JS code)

The weird thing is that now the API supports value 25.5 but not e.g. 24.75 – would it have been too hard to allow all decimal numbers here?