Still having problems with fractions

Hi Rapyd,

We still see errors what trying to create payments with fractions:
{"status":{"error_code":"UNAUTHENTICATED_API_CALL","status":"ERROR","message":"","response_code":"UNAUTHENTICATED_API_CALL"

when calling with {"amount":876.20, ...,"country":"SE","currency":"USD","merchant_reference_id":"11851","capture":false,....,"language":"en","payment_method_type_categories":["card"]}

while calling with {"amount":876, ...."country":"SE","currency":"USD","merchant_reference_id":"11852","capture":false,...,"language":"en","payment_method_type_categories":["card"]}

is working fine.

How come that we’re not allowed to ask for an amount with a fraction?

OK - it seems that I can as well get the request to go through when the amount is 876.12 - so this appears that you guys (I’m looking at you Rapyd) have broken the contract (again).

I’ll bet that if I request with 876.2 and not 876.20 the request will be fine again. This means that the code I posted here: Problem with signature - #4 by onesoft isn’t working anymore.

Will I need to change the code at my end - and if I do - how long will that work? When will you decide to break the contract again?

/Henrik

Hi, Henrik! :slight_smile:

This issue is caused by using JavaScript or Python, which truncate zeroes to the right of the decimal point, which alters the result of the signature generation process. The solution is to create a wrapper in your code. That might be as simple as sending numbers as strings, or it might be a bit more complex. I don’t have any more details about that.

If you are getting this with another programming language, then let me know and I will chase down the answer for you.

Hi @CharlesDorsett,
Actually, the problem is the other way around - I’m not using JavaScript or Python, I’m using c# and my problem was that my code wasn’t truncating the zeros - but I have updated my code now so that I don’t have this problem for the moment.

Still, it’s really strange that Rapyd is so bad coded that it can’t tell what is wrong but just yields UNAUTHENTICATED_API_CALL.

For who it may benefit - here is my current code, that can make payment request for both 1.00, 1.20 and 1.21 (hence for 1, 1.2 and 1.21):

public class RoundedCurrencyAmount
    {
        [Localizable(false)] private static readonly string[] _threeDigitsCurrencies = { "BHD", "IQD", "JOD", "KWD", "LYD", "OMR", "TND" };
        [Localizable(false)] private static readonly string[] _zeroDigitsCurrencies = { "ISK" };
        [Localizable(false)] private static readonly string[] _fourDigitsCurrencies = { "CLF", "UYW" };

        private decimal _amountTotal { get; };

        public RoundedCurrencyAmount(decimal amountTotal, string currencyIsoCode)
        {
            CurrencyIsoCode = currencyIsoCode;
            _amountTotal = GetCurrencyRounded(amountTotal, currencyIsoCode);
        }

        public string CurrencyIsoCode { get; }

        [Localizable(false)]
        public override string ToString()
        {
            return _amountTotal.ToString("#0.####", CultureInfo.InvariantCulture);
        }

        public decimal Value()
        {
            return _amountTotal;
        }

        private decimal GetCurrencyRounded(decimal amount, string currencyIsoCode)
        {
            if (_zeroDigitsCurrencies.Contains(CurrencyIsoCode))
                return Math.Round(amount, 0);

            if (_threeDigitsCurrencies.Contains(currencyIsoCode))
                return Math.Round(amount, 3);

            if (_fourDigitsCurrencies.Contains(CurrencyIsoCode))
                return Math.Round(amount, 4);

            return Math.Round(amount, 2);
        }
    }

class RoundedCurrencyAmountJsonConverter : JsonConverter
    {
        public override bool CanRead => false;

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override bool CanConvert(Type objectType)
        {
            return objectType == typeof(RoundedCurrencyAmount);
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            var item = (RoundedCurrencyAmount)value;
            writer.WriteRawValue(item.ToString());
        }
    }


Hi - I finally have an answer for you. Apparently, if you send the amount as a string instead of a number, the trailing zeroes do not get truncated off. I tested this using Postman, but it would be great to know if this works for you using C#. I see this line in your code

_amountTotal.ToString("#0.####", CultureInfo.InvariantCulture);

and I wonder if this adds the double quotes to the body string. Please let me know. If it doesn’t work, I will go back to the engineers and get a better solution.

1 Like