CoreWallet provides generic fee handling that can be used by business processes to attach fees to certain events, such as funding a wallet-account. The fee module ensures that the fee amounts are properly calculated (including proper rounding according to the currency definitions), and applied in the appropriate context.
Fee definitions can be grouped in Fee Groups, so that for specific wallets you can define non-standard fees. Wallets can be optionally assigned to a specific Fee Group, instead of using the subsidiary-default Fee Group.
The fee module provides Fee Definitions that define how a fee is calculated for a given context.
The following parameters are used to determine if a Fee Definition applies to a given context:
- Subsidiary - if set, the fee will only apply to wallets/accounts that belong to the given subsidiary
- Fee group - if set, the fee will only apply when the wallet/account belongs to the given Fee Group
- Custom type - if set, the fee will only apply for transactions with the given custom-type (which is an extension point)
- Fee context - defines the transactional context that the fee applies to, e.g. funding a wallet. The set of fee context values can be extended to allow to define fees for product-specific transaction processes.
- Amount range - if set, the fee will only apply to a transaction in the given amount range
- Currency - if set, the fee will only apply to transactions with the given currency
- Wallet country - if set, the fee will only apply for wallets in the given country
- Wallet type - if set, the fee will only apply for wallets with the given type (e.g. full or guest)
- User verification level - if set, the fee will only apply for users that have the given verification level (e.g. unverified or verified)
- Payment method - if set, the fee will only apply for transactions with the given payment-method
- Timestamp range - if set, the fee will only be applied if the current timestamp is in the given range
Each Fee Definition specifies the fee calculation parameters in a linear manner (base-amount and a rate, with a minimum and maximum fee amount, and a fee granularity).
FeeCalculationService takes these parameters and calculates the fee based on the transaction amount. The total fee is determined by adding the calculated fee amount for each applicable Fee Definition.
FeeCalculationService has 2 separate methods:
- calculateFees() - to calculate the fees, but not store any Fee Instances. This is typically done to preview the fees for a transaction, without actually preparing them for booking in the accounting module.
- calculateAndStoreFees() - to calculate the fees, and store a Fee Instance for each applied Fee Definition. This is typically used when the transaction is confirmed, and must be booked in the accounting module.
When booking a transaction in the accounting module via an Accounting Handler, the Fee Instances are used by the
FeeAccountingHandler to create the appropriate transfers.
Adding a new Fee
The following steps should be taken to add a new Fee, e.g. in a product-specific transactional process (e.g. buying a Bitcoin in a transaction called 'ExchangeDeal'):
- Define the Fee context e.g. as 'ExchangeDeal' - this makes sure that the Fee Definitions can be defined for this context
- Adjust the ExchangeDealService to call the
FeeCalculationService.calculateAndStoreFees()to determine the fees and store Fee Instances, based on the following data:
- Wallet Account - the Wallet Account that the ExchangeDeal is taking place on
- Fee context - equal to 'ExchangeDeal' here
- Transaction amount - equal to '1 Bitcoin'
- Payment method - not applicable here
- Ensure ExchangeDeal DB entity implements the
FeeInstanceOwnerinterface, and store the fee-amount and fee-amount-lead-currency after calculation
- Adjust the ExchangeDealAccountingHandler to book the fees when the ExchangeDeal reaches the appropriate state using
FeeAccountingHandler.createFeeTransfers(), which also takes care of transferring the applicable VAT amounts to the proper accounts.
- Ensure the fee-amount is set in any applicable WalletAccountItem that is created, so that the user is properly informed about what fees have been applied.
- Create Fee Definitions via the Admin UI or via a DB script