This was a fun challenge
Here is my current solution for c#:
RoundedCurrencyAmount to hold the amount and take care of the rounding
public class RoundedCurrencyAmount
{
private static readonly string[] _threeDigitsCurrencies = {"BHD", "IQD", "JOD", "KWD", "LYD", "OMR", "TND"};
private static readonly string[] _fourDigitsCurrencies = { "CLF", "UYW"};
private readonly decimal _amountTotal;
public RoundedCurrencyAmount(decimal amountTotal, string currencyIsoCode)
{
CurrencyIsoCode = currencyIsoCode;
_amountTotal = amountTotal;
}
public string CurrencyIsoCode { get; private set; }
[Localizable(false)]
public override string ToString()
{
if (_amountTotal % 1 == 0)
return _amountTotal.ToString("F0", CultureInfo.InvariantCulture);
if(_threeDigitsCurrencies.Contains(CurrencyIsoCode))
return _amountTotal.ToString("F3", CultureInfo.InvariantCulture);
if (_fourDigitsCurrencies.Contains(CurrencyIsoCode))
return _amountTotal.ToString("F4", CultureInfo.InvariantCulture);
return _amountTotal.ToString("F2", CultureInfo.InvariantCulture);
}
}
The request class:
public class RapydCreateCheckoutPageRequest
{
public RapydCreateCheckoutPageRequest(decimal amountTotal, string currencyCode)
{
Amount = new RoundedCurrencyAmount(amountTotal, currencyCode);
}
/// <summary>
/// The amount of the payment, in units of the currency defined in currency.
/// Decimal, including the correct number of decimal places for the currency exponent, as defined in ISO 4217:2015.
/// If the amount is a whole number, use an integer and not a decimal
/// </summary>
[JsonProperty(@"amount")]
public RoundedCurrencyAmount Amount { get; }
....
}
For serialization with newtonsoft:
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());
}
}
and finally the updated sterilizeBody function:
private static string SerializeBody(object from)
{
var s = from as string;
if(s != null)
return s;
return from != null ? JsonConvert.SerializeObject(
from,
Formatting.None,
new JsonSerializerSettings
{
Converters = new List<JsonConverter> { new RoundedCurrencyAmountJsonConverter()},
NullValueHandling = NullValueHandling.Ignore,
}
) : string.Empty;
}