Build Any Discount Model
One of the core principles our system is built upon is having flexible data structures. This schema is the means by which we can support any meter type, price-machine, rewards algorithm, or discount you may want to apply.
This document is focused on the promotions model. We will discuss:
- The discount data structure
- The generic discount - advanced, very flexible data structures.
- The discount templates - the more simplistic, but also more easily configurable data structures.
Generally speaking, a discount is made up of the following parts:
- Granularity
- Condition
- Discount-Model
- Measure
We will explain these notions in the next sections. For the moment let's start by introducing a high level diagram for the promotion structure:
In a usage-based pricing world, an invoice contains many prices:
- Total invoice price (before discounts)
- The total usage price --is the sum of all of the item prices--> Total Price for a specific invoiced item individually --is the sum of all of the variant prices--> Prices for each specific item variant usage individually (invoice for an item with specific dimension values)
- Total fixed fee prices -- is the sum of all the fixed fees applied-->Price for each individual fee.
Granularity is an object to let us specify the target of the discount. Currently we support the following granularities:
- Product (or plan) - both discount the total invoice price.
- Item - discount the total price for a specific invoiced item (ie. a specific Product Item).
Down the line we may include additional granularities - for example, a discount for the total usage price, or a discount on a specific fixed fee. The important thing to remember, is that each part of the invoice can be a subject to a discount.
This part answers the following questions:
- Can we apply a discount? - can we apply a discount to the customer or can we keep the current discount from the previous cycle.
- Can we use the discount at this time? - even if we can apply a discount to a customer, it's still possible that we can't use it to discount the current invoice.
Below is a diagram describing the existing discount conditions:
This condition limits a discount for a certain amount of billing-cycles, months or the min of both.
If neither 'cycles' or 'months' are provided, or if the 'promotionTimeLimit' is not provided than there is no time limit to the discount.
Schema:
A condition for keeping a discount as long as the customer is on same plan as the plan used when applying the discount.
schema:
This condition simply tells our system to start applying the discount to an account after the customer has met a certain predefined "product-level bill threshold". This "threshold" is an accumulating sum of the total price of the current and previous invoice as specified in the 'requiredHistory' of the condition.
For example, this condition would allow for a discount which may be applied after the customer spends their first $1,000, regardless of how many billing cycles it takes to reach this threshold.
Schema:
This condition is very similar to the Product-level Price-Threshold condition. This condition looks at the total price of a specific product item, as opposed to the total price of the entire product usage.
Schema:
This discount condition doesn't impose any condition for applying the discount. Instead, it tells our system to start using a discount on the next month from the moment it was assigned.
This special "condition" is just to serve as a placeholder for condition in cases where we don't wish to specify any.
Schema:
The "and condition" is just a simple way to combine multiple conditions using an 'and' clause.
Schema:
This is the actual discount model we apply on the current invoice.
We currently support the following models:
This isn't a concrete model but rather a parent class of all of our existing models.
A "Model with Max" discount model comes with an optional total max discount (since the discount was applied) an optional billing cycle max discount.
A constant discount for the entire bill (can be the product item or the entire product bill depending on the granularity).
Schema:
The discount is a constant ratio of the total price (can be for a product item or the entire product bill depending on the granularity).
Schema:
This discount is similar to the absolute case, only in this case the discount amount is determined according to the total invoice price using some predefined discounting tiers.
Schema:
Example:
The configuration above represents a tiered absolute discount of:
- $1 for any total price between $50 to $100.
- $10 for any total price of $100 or higher.
The tiered relative discount is more of a flexible case, and can actually contain the following two discounting algorithms:
- CHOOSE_SINGLE_TIER - the discount amount is determined according to the total invoice price using some predefined tiers and applied to the entire discountable price.
- STEP_FUNCTION - this option can be thought of in the same way income tax amounts are calculated. We split the total discountable price value into intervals (ranging from 0 to inf) where each interval starting point is marked as 'Ai' and identify the interval. Then the total discount is: total discount = sum over all Ai-s of Max(0, Min(Ai+1 - Ai, price-value - Ai)) * Discount-Ai
Schema:
For example, let's assume the following tiers:
Now, for a price of $1050.
With 'CHOOSE_SINGLE_TIER' we will calculate a discount of: 1050 * 0.06 = $63 discount
With 'STEP_FUNCTION' we will calculate a discount of: 100 0.00 + (1000 - 100) 0.05 + (1050 - 1000) * 0.06 = 0 + 45 + 3 = $48 discount
Before moving forward to the different discount object types, let's cover one last (advanced object).
The discount model itself can work on the price, but can also work on:
- The usage using the average item price for each invoiced unit.
- A batch of usage using the item p
Imagine that you want to give an absolute discount for an item-invoice.
An item invoice contains the:
- The total amount of usage for the item.
- The total price of the item usage.
Now, here are the options for giving an absolute discount for an invoiced item:
- TotalPrice - A discount of $X for the entire bill (bill can be product item-level or product-level depending on the granularity).
- PerUnit - A discount of $Y for each invoiced unit of usage invoiced.
- PerUnitBatch - A discount of $Z for each batch of N units of usage invoiced.
For example, you can give a $100 discount for the entire item-bill, but you can also give, let's say $0.01 for each invoiced unit of usage.
Total Price Schema:
Per Unit Schema:
Per Unit Batch Schema:
Generic models are the most advanced data structure we have. They are only available on the API and they allow you to create a specific discount if this isn't captured by any of the templates (mentioned below). As a rule of thumb, because generic discounts are more difficult to configure, we suggest you to first see if there is a template that fits your needs, and only if not consider using a generic promotions.
We currently support two types of generic models:
Schema:
Example 1:
Below is an example for a product (granularity), time-limited (condition), relative (discount model) discount. Please compare it with the example for "Time Limited Relative Product Discount" below.
Example 2: A relative product-level discount with the following conditions:
- A total accumulating product price of $10 over the last 6 month (including current).
- A time limit of 18 months since the discount was first applied.
(Naturally you are less likely to configure such a discount, what we wanted to convey with this example is the flexibility of this schema.)
Schema:
Example 1:
Below is an example for an item (granularity), time-limited (condition), relative (discount model) discount. Please compare it with the example for "Time Limited Relative Product Discount" below.
Example 2:
Below is an example for an item (granularity), time-limited (condition), relative (discount model) discount - exactly as in example-1. But we also added a constraint to it, that the discount can only be applied towards usage with the following dimension's values:
- cloudProvider = AWS
- region = us-west-2
Example 3: A relative item discount with the following conditions:
- A total accumulating item price of $10 over the last 5 invoices (including current).
- A total accumulating product price of $500 over the last 5 invoices (including current).
- The plan wasn't changed since the discount has started.
- A time limit of 12 months since the discount was first applied.
(Naturally you are less likely to configure such a discount, what we wanted to convey with this example is the flexibility of the schema.)
Template are the most common forms of discounts we see; because they represent patterns of discounts that repeats themselves, we wrapped them in an easy-to-use configuration.
Below is a list of the currently available templates:
Granularity: Product Condition: Time-Limited Discount Model: Absolute
Schema:
Example:
In the example below we create a new discount which is limited to 12 months since the moment it is applied to a customer. The discount itself targets the entire invoice bill, and it can give a discount of up to $25 per invoice, or up to $100 for all consecutive invoices since the discount was applied.
Granularity: Item Condition: Time-Limited Discount Model: Absolute
Schema:
Example:
In the example below we create a new discount which is limited to 12 months since the moment it is applied to a customer. The discount itself targets the entire invoice of a single item usage ("552a8bf2-864e-4f89-87b0-0962aaec5cdf"), and it can give a discount of up to $10 per invoice, or up to $50 for all consecutive invoices since the discount was applied.
Granularity: Product Condition: Time-Limited Discount Model: Relative
Schema:
Example:
In the example below we create a new discount which is limited to 18 billing cycles since the moment it is applied to a customer. The discount itself gives a 10% discount on the top of the entire bill (up to $100 for all consecutive invoices since the discount was applied).
Granularity: Item Condition: Time-Limited Discount Model: Relative
Schema:
Example:
In the example below we create a new discount which is limited to 18 billing cycles since the moment it is applied to a customer. The discount itself gives a 10% discount on the top of the usage cost of item "acde888f-7720-4138-918d-f9442febc96e" (and up to $100 for all consecutive invoices since the discount was applied).
Granularity: Product Condition: Time-Limited Discount Model: Tiered-Absolute
Schema:
Example:
In the example below we create a new discount which is not limited in time. The discount itself works on the entire bill, and it gives a $1 discount for the first $1 spent, and $2 discount if the invoice is $10.
Example:
In the example below we create a new discount which is limited to 3 months. The discount itself works on the entire bill, and it gives a $1 discount for the first $1 spent per invoice, and $2 discount if the total amount of all of the invoices that occurred since the discount was applied is $10 or more.
Granularity: Item Condition: Time-Limited Discount Model: Tiered-Absolute
Schema:
Example:
In the example below we create a new discount which is not limited in time. The discount itself works on the usage bill of item "2d59a1d5-31d7-409d-9d78-843f31eb3e08", and it gives a $1 discount for the first $1 spent, and $2 discount if the invoice is $10.
Granularity: Product Condition: Time-Limited Discount Model: Tiered-Absolute
Schema:
Example:
In the example below we create a new discount which is limited to 18 billing cycles. The discount itself works on the entire invoice, and it gives a 10% discount for the first $10 spent, and 20% discount for any larger amount. There is a max of $19 per cycle and $100 for the entire life time of the discount. The discount itself is calculated using the "step_function" method mentioned above.
Granularity: Item Condition: Time-Limited Discount Model: Tiered-Absolute
Schema:
Example:
In the example below we create a new discount which is limited to 18 billing cycles. The discount itself works on the usage cost of item "806fdb8e-5bce-4b24-b6ce-ab37ef857e89", and it gives a 10% discount for the first $10 spent, and 20% discount for any larger amount. There is a max of $25 per cycle and $100 for the entire life time of the discount. The discount itself is calculated using the "step_function" method mentioned above.