Add a New Currency

This document describes the necessary steps to configure a new currency in the CoreWallet.

Process outline

  1. Create a DB script to configure the new currency and exchange rates to the lead-currency (EUR)
  2. Configure the currency in the WalletAccountingConfiguration
  3. Configure the currency in the wallet ProductConfiguration
  4. Configure payment methods if required
  5. Configure limits if required
  6. Configure fees if required

1. Create DB script

A DB script is needed to configure the currency in the DB, including exchange rates to/from the lead-currency (typically EUR). This ensures future DB scripts that require the currency function properly when a new DB is setup from scratch.

An example DB script which configures CHF with 2 decimal digits and exchange rate to/from EUR:

INSERT INTO `acc_currency_info` (`currency_code`, `decimal_offset`, `default_format`, `description`, `name`) VALUES ('CHF', 2, '%s %01.02f', 'CHF', 'CHF'),
INSERT INTO `acc_exchange_rate` (`creation_datetime`, `external_reference_id`, `qualifier`, `rate`, `subsidiary_id`, `valid_from_datetime`, `valid_until_datetime`, `currency_from`, `currency_to`) VALUES
(UTC_TIMESTAMP(), 'Dummy rate', 'default', 1.2155400000, 1, UTC_TIMESTAMP(), NULL, 'EUR', 'CHF'),
(UTC_TIMESTAMP(), 'Dummy rate', 'default', 0.8226796321, 1, UTC_TIMESTAMP(), NULL, 'CHF', 'EUR');

2. Configure WalletAccountingConfiguration

The WalletAccountingConfiguration defines what financial processes are allowed in the wallet. The new currency must be configured here as well, if any processes need to work. Please note that each product typically has its own WalletAccountingConfiguration, the changes should of course only be applied there.

In com.trimplement.wallet.server.wallet.impl.wallet.process.DefaultWalletAccountingConfigurationProviderImpl.createDefaultWalletAccountConfiguration() we add it to the non-default currencies, if we use more decimal digits that the default:

// Non-default currencies
addAdditionalCurrency("CHF", 8, "%s %01.08f", "Swiss Franc", "Standard Swiss Franc currency with 8 decimal digits");

3. Configure wallet ProductConfiguration

The wallet ProductConfiguration defines what business processes are allowed in the wallet. The new currency must be configured here as well. Please note that typically each product has its own dedicated ProductConfiguration, the changes should of course only be made there.

In com.trimplement.wallet.server.wallet.impl.product.dom.DefaultProductConfigurationImpl.createDefaultProductConfiguation() we add the currency to the supported-transaction-currency and supported-wallet-currency.

getSupportedTransactionCurrencies().addAll(Arrays.asList(..., CHF));
getSupportedWalletAccountCurrencies().addAll(Arrays.asList(..., CHF));

If we want to create a new wallet-account in this currency for a particular country when a new wallet is created by default, we add it as well:

getInitialWalletAccountCurrenciesByCountryCode().put(CountryCode.CH, Arrays.asList(CHF));

If we want to allow Vouchers in the currency, we configure it in com.trimplement.wallet.server.wallet.impl.product.dom.DefaultProductConfigurationImpl.voucherConfiguration.

If we want to configure Payment-Approvals for the currency, we can do it in com.trimplement.wallet.server.wallet.impl.product.dom.DefaultProductConfigurationImpl.voucherConfiguration.paymentApprovalConfiguration.

4. Configure payment-methods

E.g. remittance can be configured with the following SQL:

insert into pay_method_config (payment_method_name, currency_code)
values ('remittance', 'CHF');
insert into `pay_instrument` (`type`, `id`, `creation_date_time`, `display_value`, `owner`, `bank_name`, `bic`, `country_code`, `domestic_account_number`, `domestic_bank_zip_code`, `iban`, `search_value`, `source`)
values ('BANK_ACCOUNT',null,UTC_TIMESTAMP(),'Remittance CHF','CoreWallet','Some Bank','ABCDCHEFXXX','DE','000.000.00','0000','CH0000000000000000000','74d3e5d990c82ef4469c207d2a6603fccbda72ccea80fa046902f8f39d3351b3c4f50c97359a59e838a756d63ae9c4baed9923b4a8f6cff505887889076f0451', 'System');
insert into `pay_business_contract` (`bank_account_id`, `comment`, `subsidiary_id`, `address`, `qualifier_1`, `type`, `payment_method_name`, `qualifier_2`, `status`)
values (last_insert_id(),'Default Remittance CHF contract', 1, '', 'REMITTANCE_CREDIT', 'BANK_CONTRACT', 'remittance', 'CHF', 'Active');
set @chf_contract_id = last_insert_id();
insert into `pay_business_contract_params` (`business_contract_id`, `name`, `value`)
values (@chf_contract_id, 'RemittanceCredit.DebitorAddress0', 'Street');
insert into `pay_business_contract_params` (`business_contract_id`, `name`, `value`)
values (@chf_contract_id, 'RemittanceCredit.DebitorAddress1', 'Zip City');
insert into `pay_business_contract_params` (`business_contract_id`, `name`, `value`)
values (@chf_contract_id, 'RemittanceCredit.FileFormat', 'CSV');
insert into `pay_business_contract_params` (`business_contract_id`, `name`, `value`)
values (@chf_contract_id, 'RemittanceCredit.AmountGranularity', '0.01');

Other payment methods may require different setup.

If strict business contract routes are configured per currency (instead of the default 'allow-all' routes) then they should be added for the new currency as well.

5. Configure limits

Either per AdminAPI or SQL typical limits should be created for the new currency (e.g. min/max transaction amounts, transaction volumes, ...).

6. Configure fees

Either per AdminAPI or SQL typical fees should be created for the new currency (e.g. payment fees, trading fees, …).