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.

Amount units and currencies

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

Amounts structure

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();
⚠️ **GitHub.com Fallback** ⚠️