dealing with amounts - AEVI-AppFlow/pos-android-sdk GitHub Wiki
Dealing with money and all possible currencies can be quite a complex task. This page is intended to help you work with amounts in AppFlow in a simple and standardised way.
To keep the AppFlow models as simple as possible, money is represented as follows
- Amount value as a
long
representing the base unit for that currency - An associated
ISO-4217
three-letter currency code
ISO-4217
defines currencies via a currency number, code and more importantly in this case, the fraction relationship between the main unit and a sub-unit, if one exists. The sub-unit is what you would know as cents, pence, and so on. Not all currencies, like the Japanese Yen, have any sub-unit. See ISO-4217 Definitions for a list of currencies in this format.
Most currencies, such as the US Dollar, British Pound, EURO, etc all have a sub-unit with a fraction of 2, meaning that in the case of US Dollar, 10 dollars equals 1000 cents.
The amount value in AppFlow is defined as the main unit times the sub-unit fraction, so in the example above, a client would pass 1000
(10 * 100) for the currency code USD
.
It is up to each application to manage the currencies correctly, which is fairly easily done with the help of the Java Currency
class with which you can query for the sub-unit fractions. The snippet below shows how you can find out what the fraction is, and via BigDecimal
easily represent that for purposes such as retrieving a human readable representation, etc.
long amountValue = 1000;
String currencyCode = "USD";
Currency currency = Currency.getInstance(currencyCode);
int subUnitFraction = currency.getDefaultFractionDigits(); // This will return 2 for USD
BigDecimal amount = BigDecimal.valueOf(amountValue).movePointLeft(subUnitFraction);
String readableAmount = currency.getSymbol() + amount.toString(); // "$10.00
The Amounts
class consists of three main entities
- A base amount
- Additional amounts
- Currency
In addition, it contains the following fields for supporting currency conversions
- Currency exchange rate
- Original currency
The baseAmount
represents the actual value of goods and services. If a basket is set, the baseAmount
will reflect the basket total value. On top of this base amount, there may be additional amounts for scenarios such as
- tipping
- cashback
- fees
- charity donations
- etc
See Additional Amounts for a list of defined identifiers.
The total amount (Amounts.getTotalAmount()
) will reflect the base amount + all additional amounts.
There may be scenarios (often in payment applications), where some additional amounts are supported natively in that environment, but not others. As an example, many payment hosts/gateways supports setting tip and cashback as individual fields in the host message, but would rarely support something like charity donation. For these cases, the getTotalExcludingAmounts(String... amountsIdentifiers)
is a useful method to help calculate a base amount that includes some additional amounts. Below is an example that reflects the above scenario
// Input amounts
Amounts amounts = new Amounts(1000, "EUR");
amounts.addAdditionalAmount("tip", 200);
amounts.addAdditionalAmount("cashback", 50);
amounts.addAdditionalAmount("charityDonation", 100);
// Extract relevant amounts
// baseAmount now includes base and charityDonation, but not tip and cashback
long baseAmount = amounts.getTotalExcludingAmounts("tip", "cashback");
long tip = amounts.getAdditionalAmountValue("tip");
long cashback = amounts.getAdditionalAmountValue("cashback");
long total = amounts.getTotalAmountValue();