Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tiered fees in Product Reference data #10

Closed
CDR-API-Stream opened this issue Sep 6, 2019 · 9 comments
Closed

Tiered fees in Product Reference data #10

CDR-API-Stream opened this issue Sep 6, 2019 · 9 comments

Comments

@CDR-API-Stream
Copy link
Collaborator

Description

Amend the PRD payloads to incorporate the ability to represent tiered fees

Area Affected

Payloads of Product Detail and Account Detail

Change Proposed

The following is the detail previously posted by CBA in the main standards repo in this comment:
ConsumerDataStandardsAustralia/standards#79 (comment)

Problem Space – Tiered Fees

Commonwealth Bank want to represent fees accurately via the Open Banking specification. However the specification is restrictive for fees that leverage tiering and/or varying fee amounts (percentage or amount).

Example One - Credit Card Cash Advance Fee

Description: This fee is charged for cash advances obtained: Over the counter at CommBank branches or other Australian financial institutions. $3.00 or 3.00% of the transaction amount - whichever is greater. Capped at a maximum fee of $300.00
The credit card cash advance fee should be represented like the table below:

Transaction Value Fee Amount Fee Percentage
<$100 $3.00 -
Between $100 and $9,999 - 3%

$10,000 | $300 | -

However we are representing it like below:

{
                "name": "Cash advance fee",
                "feeType": "WITHDRAWAL",
                "transactionRate": "0.03",
                "currency": "AUD",
                "additionalValue": "3.00",
                "additionalInfo": "This fee is charged for cash advances obtained: Over the counter at CommBank branches or other Australian financial institutions. $3.00 or 3.00% of the transaction amount - whichever is greater. Capped at a maximum fee of $300.00 (or $3 if your closing balance was in credit the previous business day). We’re unable to block cash advance transactions that aren’t sent to us for authorisation. These will attract interest from the date the transaction is made until it’s repaid."
}

Example Two – Corporate Charge Card Annual Fee
Description: 1-49 cards $40.00 per card, 50-499 cards $32.00 per card, 500+ cards $24.00 per card
The Annual Fee should be represented like the table below:

Annual Fee Card Count
$40 1-49
$32 40-499
$24 500+
However we are representing it like below:

{
                "name": "Annual fee",
                "feeType": "PERIODIC",
                "amount": "40.00",
                "currency": "AUD",
                "additionalValue": "P1Y",
                "additionalInfo": "1-49 cards $40.00 per card"
            },
            {
                "name": "Annual fee",
                "feeType": "PERIODIC",
                "amount": "32.00",
                "currency": "AUD",
                "additionalValue": "P1Y",
                "additionalInfo": "50-499 cards $32.00 per card"
            },
            {
                "name": "Annual fee",
                "feeType": "PERIODIC",
                "amount": "24.00",
                "currency": "AUD",
                "additionalValue": "P1Y",
                "additionalInfo": "500+ cards $24.00 per card"
            }

We have many examples where pricing is a mix of percentage or amount depending on the size of the transaction. Additionally we have fee where a counter number of transactions are free, then multiple levels of pricing apply depending on the quantity.

Recommendation

We recommend that tiering gets added to the open banking specification to support the above use cases.

BankingProductFeeTier Definition

Name Type Required Restrictions Description
name string mandatory none A display name for the tier
unitOfMeasure string mandatory none The unit of measure that applies to the tierValueMinimum and tierValueMaximum values e.g. 'DOLLAR', 'PERCENT', ‘TRANSACTION_COUNT’
minimumValue number mandatory none The number of tierUnitOfMeasure units that form the lower bound of the tier. The tier should be inclusive of this value
maximumValue number optional none The number of tierUnitOfMeasure units that form the upper bound of the tier or band. For a tier with a discrete value (as opposed to a range of values e.g. 1 month) this must be the same as tierValueMinimum. Where this is the same as the tierValueMinimum value of the next-higher tier the referenced tier should be exclusive of this value. For example a term deposit of 2 months falls into the upper tier of the following tiers: (1 – 2 months, 2 – 3 months). If absent the tier's range has no upper bound.
rateApplicationMethod string optional none The method used to calculate the amount to be applied using one or more tiers. A single rate may be applied to the entire balance or each applicable tier rate is applied to the portion of the balance that falls into that tier (referred to as 'bands' or 'steps')
applicabilityConditions   optional none Defines a condition for the applicability of a tiered rate
Then we could model our pricing more accurately.
Example one modelled in the new world…..


     {
                "name": "Cash advance fee",
                "feeType": "WITHDRAWAL",
                "amount": "3.00",
                "currency": "AUD",
                "tiers": [
		{
"name": "Cash advance fee tier",
"unitOfMeasure": "DOLLAR",
"minimumValue": "0.00",
"maximumValue": "100.00",

         }	
        ]},

{
                "name": "Cash advance fee",
                "feeType": "WITHDRAWAL",
                "transactionRate": "0.03",
                "currency": "AUD",
                "tiers": [
		{
"name": "Cash advance fee tier",
"unitOfMeasure": "DOLLAR",
"minimumValue": "100.01",
"maximumValue": "9999.99"
         }	
        ]},
{
                "name": "Cash advance fee",
                "feeType": "WITHDRAWAL",
                "amount": "300.00",
                "currency": "AUD",
                "tiers": [
		{
"name": "Cash advance fee tier",
"unitOfMeasure": "DOLLAR",
"minimumValue": "10000.00"
         }	
        ]}
@CDR-API-Stream
Copy link
Collaborator Author

After analysis the DSB would recommend the proposed change with the variation that the tier field would be an alternative to the existing conditional fields (amount/balancerate/etc) and would include the amount applicable to the tier. This would allow clear distinction between tiered fees (which are likely to be in the minority) and simple fees and will also ensure that all tiers are clearly aggregated under a single fee type.

It is believed that this will achieved the intent of the request but be more readable for client applications.

For example the Cash Advance Fee in the issue description would be represented as:

{
    "name": "Cash advance fee",
    "feeType": "WITHDRAWAL",
    "currency": "AUD",
    "tiers": [
        {
            "transactionRate": "0.05",
            "unitOfMeasure": "DOLLAR",
            "minimumValue": "0.00",
            "maximumValue": "100.00"
         },
        {
            "transactionRate": "0.03",
            "unitOfMeasure": "DOLLAR",
            "minimumValue": "100.01",
            "maximumValue": "9999.99"
         }
     ]
}

@perlboy
Copy link

perlboy commented Nov 20, 2019

Is there a reason a "tier" is not defined as a parent object with variation objects included, essentially a 1 to Many Tiers to Many values versus the flat 1 to Many Tiers for Rates and, as proposed now, Fees? As a start, having a tier identifier that allowed for relationships to be established would be more readable for client applications. "Sub Tier" seems to indicate this but it also seems to limit attributes that make it easy to enforce referential integrity.

As with the interest rates data the parsing of tier information currently purely based on a unique key across 4 values with significantly different meanings (DOLLAR vs. MONTH) is not particularly easy to deal with. By way of example Biza.io has encountered various challenges due to this non-deterministic behaviour as Holder's have presented tiering data is various ways.

Using the same rendering method this has resulted in inconsistent presentation across the Holders which would be more readily solved if the tier (and consequently sub-tier) was made referentially rigid. Mortgages will also make this more problematic.

Here is Westpac's TDTermDeposit rate table, note frequencies are limited options:
image

With the same rendering method here is NAB's Term Deposit (5b6fd42e-a4c7-4457-b6c3-71b1dc191b72), note that frequencies is a mess of drop downs and the rate table is a single value of range:

image

Both pass the Data61 Conformance Suite.

It seems appropriate that the approach taken handling tiering for rates and fees be consistent and that consumers can render them in a programmatically consistent way. As there are now people building to consume these APIs it seems likely this change will result in a new endpoint version.

@CDR-API-Stream
Copy link
Collaborator Author

At the completion of consultation and with reference to the discussion at the open teleconference last Wednesday the recommendation of the DSB above will stand but a review of tiering with a view to rationalising the structures will be examined in a future iteration.

@commbankoss
Copy link

commbankoss commented Nov 25, 2019

Commonwealth Bank does not support the changes as proposed to address tiered pricing. There is a need to create a consistent design pattern between rates and fees to simplify interpretation for consumers and data recipients. The Data61 proposal is inconsistent with the current standards for both deposit and lending rate tiering.

The recommended treatment outlined by Commonwealth Bank is consistent with the treatment for both deposit and lending rate tiering. The approach improves the consistency of information for data recipients. This would be a backwards compatible additive change using industry standard approaches to API versioning.

To provide clarity, what we have proposed is an optional tier, which would follow the same pattern present in both the deposit and lending rate property - BankingProductRateTier.

tiers [BankingProductRateTier] optional none Rate tiers applicable for this rate

Current Standard -

"fees":  [{
                "name": "Annual fee",
                "feeType": "PERIODIC",
                "amount": "40.00",
                "currency": "AUD",
                "additionalValue": "P1Y",
                "additionalInfo": "1-49 cards $40.00 per card"
            },
]

Proposed change -

"fees": [{
               "name": "Cash advance fee",
               "feeType": "WITHDRAWAL",
               "amount": "3.00",
               "currency": "AUD",
               "additionalValue": "",
               "additionalInfo": ""  ,             
      
               "tiers": [
                              {
                                "name": "Cash advance fee tier",
                                "unitOfMeasure": "DOLLAR",
                                "minimumValue": "0.00",
                                "maximumValue": "100.00",
                               }        
                           ]
              },
             ]

Commonwealth Bank understands that there are considerations for greater enhancements to the Standards which could require a breaking change. What we have proposed is a solution that may be implemented by Data holders post go-live without creating a dependency on changes to the Standards. The Commonwealth Bank recommends that additive change be treated as non-breaking in general, and notes that the various versioning approaches defined in the Standards could be leveraged to allow explicit change.

The proposed approach follows the same design intent and further enhances the machine readability of the schema, allowing clear and transparent publication of pricing information. Commonwealth Bank recommends that the amendment be a backlog item as a priority for the current iteration of the Standards.

@perlboy
Copy link

perlboy commented Nov 26, 2019

Is the intent of the DSB's proposal to suggest that a fee is correlated to a specific rate tier? With reference to the example given:

{
    "name": "Cash advance fee",
    "feeType": "WITHDRAWAL",
    "currency": "AUD",
    "tiers": [
        {
            "transactionRate": "0.05",
            "unitOfMeasure": "DOLLAR",
            "minimumValue": "0.00",
            "maximumValue": "100.00"
         },
        {
            "transactionRate": "0.03",
            "unitOfMeasure": "DOLLAR",
            "minimumValue": "100.01",
            "maximumValue": "9999.99"
         }
     ]
}

This appear to suggest a Cash Advance Withdrawal fee of 5c and 3c charged on transactions of either $0->$100 or $100->9999. Or it is a cash advance fee with no value based on an interest rate (derived from lending rates presumably) and balance value. Neither of these scenarios appear to be likely and/or correct?

In order to avoid unnecessary rework and as outlined in the conference call Biza.io recommends that further consideration be given to this change and immediate changes not be made until such time as there is reasonable consideration and consensus the proposed change will be suitable to Holder's product use cases.

Biza wishes to reiterate the comments made in the call and in other threads that consideration be given for a tier identifier which could be used across fee descriptions. This would represent a significant decrease in work effort for effective rendering of fees and rates alike.

Not withstanding @commbankoss's proposal, Biza repeats once again that this change be delayed until such time as there is suitable alignment of participants. As it stands this change affects Optional components of the existing payload and does not appear to be an urgent change so we are confused as to why it is being prioritised within the maintenance repository.

@CDR-API-Stream
Copy link
Collaborator Author

It would appear that more discussion on this topic is required so no recommendation will be made in this iteration. According to our published operating model there are now three ways of addressing this issue:

  1. Continue consultation and include the issue in the backlog for the next iteration
  2. Mark the issue as an emergency change (if a justification exists) and deal with it out of cycle
  3. Elevate the issue to a dedicated Decision Proposal and consult on the main standards site

The DSB has no specific preference. Feedback on the community's preferred option is sought.

@CDR-API-Stream
Copy link
Collaborator Author

In response to the feedback provided above:

@commbankoss wrote:

To provide clarity, what we have proposed is an optional tier, which would follow the same pattern present in both the deposit and lending rate property - BankingProductRateTier.

This was understood in the original proposal. The note provided in the DSB's original feedback on the proposal was that this would overly complicate the tiering of fees which do not appear to be as complicated as rate tiers that can be highly complex and multi-dimensional. Following the pattern applied for rates will result in the consumer of the payload needing to correlate tiers based on the name of the fee, which is a display string and not an identifier. It is true that the proposed tier model is different than that used for rates but it is believed that this is commensurate with the different level of complexity required and would be a simpler treatment for the simpler scenario. The feedback provided did not address this concern raised by the DSB but asserted that consistency with rates would make it easier for consumers of the data which does not appear to be self-evident.

@perlboy wrote:

This appear to suggest a Cash Advance Withdrawal fee of 5c and 3c charged on transactions of either $0->$100 or $100->9999. Or it is a cash advance fee with no value based on an interest rate (derived from lending rates presumably) and balance value. Neither of these scenarios appear to be likely and/or correct?

The sample given was simply to illustrate the proposed structure and was aligned with the sample provided in the issue description. Note that transactionRate is a percentage the example given implies a 5% fee applied to a smaller transaction amount and a 3% fee being applied to the larger transaction amount.

@perlboy wrote:

Biza wishes to reiterate the comments made in the call and in other threads that consideration be given for a tier identifier which could be used across fee descriptions. This would represent a significant decrease in work effort for effective rendering of fees and rates alike.

This approach has been considered but has not been pursued as the tiering for fees and rates do appear to be correlated in any way. Fees are usually transaction oriented whereas lending rates based on the loan amount. Even if the fee and rate tiers are both using the amount invested or lent there is no reason that the thresholds for the tiers will be the same. In summary, it appears logical to treat the tiering data is an attribute of a rate or fee and not the other way around.

That said, it may be that the model being proposed is not well understood. If an example could be provided that may help the proposal to be properly understood.

@NationalAustraliaBank
Copy link

NAB agrees that tiering for fees is a necessary addition to allow an accurate representation of some Fees, however more examples need to be worked through to understand impacts and drive consistency across the data holders.

We recommend raising a dedicated Decision Proposal to allow options to be tabled and discussed.

@anzbankau
Copy link

anzbankau commented Nov 28, 2019

ANZ supports the original @commbankoss proposal for Fees to follow the pattern used for interest rate tiering. In the same way that DepositRates and LendingRates are arrays of actual rates, Fees should be an array of actual fees. The categorisation/classification into fee types (e.g. ‘Cash Advance’) should be considered attributes rather than an aggregating first-class object. The CDR-API-Stream counter-proposal puts the ‘sub-feeType’ (with name property) as a structural element above the fees with the fees pushed down into FeeTier, meaning that only one fee dimension/tier set could be supported (as noted). However, this also requires the full set of conditional fields (amount, balanceRate, transactionRate, acrruedRate) to be pushed down into FeeTier. As noted in @CDR-API-Stream 's response, the counter-proposal erroneously uses only transactionRate rather than tier1($0-100: amount = $3), tier2($100-9999: transactionRate = 3%) and tier3(>=$10000: amount = $300).

While the RateTier schema is simple and generic in supporting the ‘criteria’ by which a consumer would qualify for the tier, the FeeTier schema would represent the fee itself. The two *Tier schema would not only be vastly different in structure, but also in concept and use. A data consumer should be able to use the same pattern for RateTier and FeeTier – further minimising the impact of extensions. While fees currently don’t have multiple dimensions, they may well need them in the future.

@CDR-API-Stream is right to say ‘needing to correlate tiers based on the name of the fee, which is a display string and not an identifier’. However this points to the need for feeType (e.g. ‘WITHDRAWAL’) to be feeClass to allow feeType to be more granular typing (e.g. ‘CASH_ADVANCE’). The expeditious nature of the standards formulation and the need to minimise changes did not lead to a comprehensive multi-level classification scheme (with type enumerations) in any area of the standards to help data consumers (the ultimate objective of standardisation). We hope this will be addressed in subsequent iterations of the data standard.

Note that RateTier.name is currently used as the name of the ‘tier set’, not the tier itself. For example, all tiers with month ranges for a term deposit should have RateTier.name = ‘Term’ – essentially the ‘row super-heading’ for the two-dimensional table of Term vs Interest Payment Frequency. This is another example of considering elements of the RateTier to be the tier itself, with the name being used for aggregation. There should really be a RateTier.TierSetUType enumeration in the standard so that RateTier.name can be more like a name (e.g. '1-2 Months'), but in the interim a free-text name field is used. Given that the Data Providers produce the tier sets there should be no doubt that their tiers can be reliably aggregated by the RateTier.name field – as is the case for the FeeTier.name field e.g. 'Cash advance fee'. Data consumers must deal with differences between Data Provider’s RateTier.name (and FeeTier.name) values until these are standardised through enumerations.

Note: In reference to @perlboy 's post, BankingProductRateTier.subTier should have been marked as deprecated as its removal was not accepted by James in a joint teleconference well before version 1 of the standards were locked down – on the basis that it was a structural change at a time when he wanted to minimise changes. It is simply a hang-over from the first version of the interest rate tiering model. As demonstrated in the example live products provided by two banks and the problem with consuming them both, the standards should not provide two structural mechanisms to represent the same concepts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

No branches or pull requests

5 participants