Build any Promotion or Discount Model (Promotions Engine)

Introduction

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:

  1. The promotion data structure.
  2. The generic promotions - advanced, very flexible data structures.
  3. The promotion templates - the more simplistic, but also more easily configurable data structures.

The promotion structure

Generally speaking a promotion is made up of the following parts:

  1. Granularity
  2. Condition
  3. Discount-Model
  4. 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:

832832

Granularity

In a usage-based pricing world, an invoice contains many prices:

  1. Total invoice price (before discounts)
    1.1. 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)
    1.2. 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 promotion. Currently we support the following granularities:

  1. Product (or plan) - both discount the total invoice price.
  2. 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 promotion.


Condition

This part answers the following questions:

  1. Can we apply a promotion? - can we apply a promotion to the customer or can we keep the current promotion from the previous cycle.
  2. Can we use the promotion at this time? - even if we can apply a promotion 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 promotion conditions:

778778

Time-Limited Condition

This condition limits a promotion 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 promotion.

Schema:

---
type: "object"
properties:
  requiredHistory:
    type: "object"
    properties:
      cycles:
        type: "integer"
        description: "max amount of billing cycles this promotion can be applied (optional)"
      months:
        type: "integer"
        description: "max amount of months this promotion can be applied (optional)"
  type:
    type: "string"

Same-Plan Condition

A condition for keeping a promotion as long as the customer is on same plan as the plan used when applying the promotion.

schema:

---
type: "object"
properties:
  type:
    type: "string"
        description: "must be same_plan"

After-Product Price-Threshold Condition

This condition simply tells our system to start applying the promotion 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 promotion 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:

---
type: "object"
properties:
  minThreshold:
    type: "number"
  requiredHistory:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  type:
    type: "string"
    description: "must be after_product_price_threshold"

After-Item Price-Threshold Condition

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:

---
type: "object"
properties:
  minThreshold:
    type: "number"
  itemId:
    type: "string"
  requiredHistory:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  type:
    type: "string"
    description: "must be after_item_price_threshold"

Next Billing Cycle

This promotion condition doesn't impose any condition for applying the promotion.
Instead, it tells our system to start using a promotion on the next month from the moment it was assigned.

---
type: "object"
properties:
  type:
    type: "string"

No Condition

This special "condition" is just to serve as a placeholder for condition in cases where we don't wish to specify any.

Schema:

---
type: "object"
properties:
  type:
    type: "string"

And Condition

The "and condition" is just a simple way to combine multiple conditions using an 'and' clause.

Schema:

---
type: "object"
properties:
  conditions:
    type: "array"
    items:
      type: "object"
      description: "an array of condition objects"
  type:
    type: "string"
    description: "must be and_condition"

Promotion Model

This is the actual promotion model we apply on the current invoice.

We currently support the following models:

674674

Model with Max

This isn't a concrete model but rather a parent class of all of our existing models.

A "Model with Max" promotion model comes with an optional total max discount (since the promotion was applied) an optional billing cycle max discount.

Absolute

A constant promotion for the entire bill (can be the product item or the entire product bill depending on the granularity).

Schema:

---
type: "object"
properties:
  cycleMaxDiscount:
    type: "number"
  discount:
    type: "number"
  measure:
    type: "object"
  requiredHistory:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
        description: "must be and_condition"

Relative

The promotion is a constant ratio of the total price (can be for a product item or the entire product bill depending on the granularity).

Schema:

---
type: "object"
properties:
  cycleMaxDiscount:
    type: "number"
  discountRatio:
    type: "number"
  measure:
    type: "object"
  requiredHistory:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"

Tiered absolute

This promotion 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:

---
type: "object"
properties:
  cycleMaxDiscount:
    type: "number"
  discountValueMap:
    type: "object"
    additionalProperties:
      type: "number"
  measure:
    type: "object"
  requiredHistory:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
        description: "must be price_tiered_absolute"

Example:

{
    "discountValueMap": {
        "50": 1
        "100": 10
    },
    "type": "price_tiered_absolute",
    "measure": {
        "type": "total_price"
    },
    "requiredHistory": {
        "cycles": 0,
        "months": 0
    },
    "totalMaxDiscount": null,
    "cycleMaxDiscount": null
}

The configuration above represents a tiered absolute discount of:

  1. $1 for any total price between $50 to $100.
  2. $10 for any total price of $100 or higher.

Tiered Relative

The tiered relative promotion is more of a flexible case, and can actually contain the following two discounting algorithms:

  1. 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.
  2. 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:

---
type: "object"
properties:
  cycleMaxDiscount:
    type: "number"
  discountCalculationStrategy:
    type: "string"
    description: "STEP_FUNCTION, CHOOSE_SINGLE_TIER"
  discountRatioMap:
    type: "object"
    additionalProperties:
      type: "number"
  measure:
    type: "object"
  requiredHistory:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
    description: "must be price_tiered_relative"

For example, let's assume the following tiers:

From Price

To Price

Discount

0

100

0%

100

1000

5%

1000

inf

6%

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


Measure

Before moving forward to the different promotion object types, let's cover one last (advanced object).

The promotion model itself can work on the price, but can also work on:

  1. The usage using the average item price for each invoiced unit.
  2. A batch of usage using the item p

Why do we need the measure

Imagine that you want to give an absolute discount for an item-invoice.

An item invoice contains the:

  1. The total amount of usage for the item.
  2. The total price of the item usage.

Now, here are the options for giving an absolute discount for an invoiced item:

  1. TotalPrice- A discount of $X for the entire bill (bill can be product item-level or product-level depending on the granularity).
  2. PerUnit - A discount of $Y for each invoiced unit of usage invoiced.
  3. 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.

Schemas:

Total Price Schema:

---
type: "object"
properties:
  type:
    type: "string"
        description: "must be total_price"

Per Unit Schema:

---
type: "object"
properties:
  type:
    type: "string"
      description: "must be per_unit"

Per Unit Batch Schema:

---
type: "object"
properties:
  batchSize:
    type: "integer"
  type:
    type: "string"
    description: "must be per_batch"

Generic Promotions

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 promotion if this isn't captured by any of the templates (mentioned below). As a rule of thumb, because generic promotions 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:

GenericItemPromotion

Schema:

---
type: "object"
properties:
  condition:
    type: "object"
  description:
    type: "string"
  id:
    type: "string"
  lockingStatus:
    type: "string"
    description: "OPEN, CLOSE_TO_DELETIONS, CLOSE_TO_CHANGES, DEPRECATED"
  promotionModel:
    type: "object"
  promotionName:
    type: "string"
  promotionType:
    type: "string"
    description: "only 'DISCOUNT' is currently supported"
    default: "DISCOUNT"
  targetProductId:
    type: "string"
  type:
    type: "string"
    description: "must be generic_product_promotion"

Example 1:

Below is an example for a product (granularity), time-limited (condition), relative (discount model) promotion. Please compare it with the example for "Time Limited Relative Product Discount" below.

{
    "targetProductId": "ed7a3d38-bdd0-4db2-b047-2bc5d7b67336",
    "promotionType": "discount",
    "condition": {
        "type": "time_limited",
        "requiredHistory": {
            "cycles": 0,
            "months": 1
        }
    },
    "promotionModel": {
        "discountRatio": 0.1,
        "type": "relative",
        "measure": {
            "type": "total_price"
        },
        "requiredHistory": {
            "cycles": 0,
            "months": 1
        },
        "totalMaxDiscount": 100,
        "cycleMaxDiscount": 20
    },
    "id": "6aa33aa2-daf5-47b1-80c0-394127f383e7",
    "type": "generic_product_promotion",
    "promotionName": "55ed6c54-a201-4bfe-aaba-d9bd1b759d7c",
    "lockingStatus": "open"
}

Example 2:
A relative product-level promotion with the following conditions:

  1. A total accumulating product price of $10 over the last 6 month (including current).
  2. A time limit of 18 months since the promotion was first applied.

(Naturally you are less likely to configure such a promotion, what we wanted to convey with this example is the flexibility of this schema.)

{
    "targetProductId": "392d5b67-f49d-43c9-979b-89b296063f79",
    "promotionType": "discount",
    "condition": {
        "type": "and_condition",
        "conditions": [
            {
                "type": "after_product_price_threshold",
                "requiredHistory": {
                    "cycles": 0,
                    "months": 6
                },
                "minThreshold": 10
            },
            {
                "type": "time_limited",
                "requiredHistory": {
                    "cycles": 0,
                    "months": 18
                }
            }
        ]
    },
    "promotionModel": {
        "discountRatio": 0.1,
        "type": "relative",
        "measure": {
            "type": "total_price"
        },
        "requiredHistory": {
            "cycles": 0,
            "months": 1
        },
        "totalMaxDiscount": 100,
        "cycleMaxDiscount": 20
    },
    "id": "36577499-d2d2-478d-974a-1f34bc7464e9",
    "type": "generic_product_promotion",
    "promotionName": "0a81c207-6232-4d08-88a1-e877a87c6d53",
    "description": null,
    "lockingStatus": "open",
    "lastUpdateTimeInMillis": 0
}

GenericProductPromotion

Schema:

---
type: "object"
properties:
  condition:
    type: "object"
  description:
    type: "string"
  id:
    type: "string"
  lockingStatus:
    type: "string"
    description: "OPEN, CLOSE_TO_DELETIONS, CLOSE_TO_CHANGES, DEPRECATED"
  promotionModel:
    type: "object"
  promotionName:
    type: "string"
  promotionType:
    type: "string"
    description: "only 'DISCOUNT' is currently supported"
    default: "DISCOUNT"
  targetItemId:
    type: "string"
  type:
    type: "string"
    description: "must be generic_item_promotion"

Example 1:

Below is an example for an item (granularity), time-limited (condition), relative (discount model) promotion. Please compare it with the example for "Time Limited Relative Product Discount" below.

{
    "targetItemId": "58e0a665-5244-4d01-8e1e-c0a7a72f169a",
    "promotionType": "discount",
    "condition": {
        "type": "time_limited",
        "requiredHistory": {
            "cycles": 0,
            "months": 1
        }
    },
    "promotionModel": {
        "discountRatio": 0.1,
        "type": "relative",
        "measure": {
            "type": "total_price"
        },
        "requiredHistory": {
            "cycles": 0,
            "months": 1
        },
        "totalMaxDiscount": 100,
        "cycleMaxDiscount": 20
    },
    "id": "50aa986b-d384-4dc4-8a9e-eee1f29f46f5",
    "type": "generic_item_promotion",
    "promotionName": "1675182e-5837-48e7-8df2-41a81aa9815f",
    "lockingStatus": "open",
    "lastUpdateTimeInMillis": 0
}

Example 2:
A relative item promotion with the following conditions:

  1. A total accumulating item price of $10 over the last 5 invoices (including current).
  2. A total accumulating product price of $500 over the last 5 invoices (including current).
  3. The plan wasn't changed since the promotion has started.
  4. A time limit of 12 months since the promotion was first applied.

(Naturally you are less likely to configure such a promotion, what we wanted to convey with this example is the flexibility of the schema.)

{
    "targetItemId": "ca288a7c-9944-41d4-a7e2-d47eabce1496",
    "promotionType": "discount",
    "condition": {
        "type": "and_condition",
        "conditions": [
            {
                "type": "after_item_price_threshold",
                "itemId": null,
                "requiredHistory": {
                    "cycles": 5,
                    "months": 0
                },
                "minThreshold": 10
            },
            {
                "type": "after_product_price_threshold",
                "requiredHistory": {
                    "cycles": 5,
                    "months": 0
                },
                "minThreshold": 500
            },
            {
                "type": "same_plan"
            },
            {
                "type": "time_limited",
                "requiredHistory": {
                    "cycles": 0,
                    "months": 12
                }
            }
        ]
    },
    "promotionModel": {
        "discountRatio": 0.1,
        "type": "relative",
        "measure": {
            "type": "total_price"
        },
        "requiredHistory": {
            "cycles": 10,
            "months": null
        },
        "totalMaxDiscount": 100,
        "cycleMaxDiscount": 20
    },
    "id": "f2aac76a-840a-4608-b268-bae52615e637",
    "type": "generic_item_promotion",
    "promotionName": "d6a2eb2a-91f5-407d-bde9-2bfa2f1d6e7d",
    "description": null,
    "lockingStatus": "open",
    "lastUpdateTimeInMillis": 0
}

Templates

Template are the most common forms of promotions we see; because they represent patterns of promotions that repeats themselves, we wrapped them in an easy-to-use configuration.

Below is a list of the currently available templates:

Time-Limited Absolute Product Discount

Granularity: Product
Condition: Time-Limited
Discount Model: Absolute

Schema:

---
type: "object"
properties:
  description:
    type: "string"
  discount:
    type: "number"
  id:
    type: "string"
  lockingStatus:
    type: "string"
    description: "OPEN, CLOSE_TO_DELETIONS, CLOSE_TO_CHANGES, DEPRECATED"
  promotionName:
    type: "string"
  promotionTimeLimit:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  targetProductId:
    type: "string"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
    description: "must be time_limited_absolute_product_discount"

Example:
In the example below we create a new promotion which is limited to 12 months since the moment it is applied to a customer. The promotion 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 promotion was applied.

{
    "targetProductId": "4d228d9e-0683-4636-b21f-81c4127298dc",
    "promotionTimeLimit": {
        "cycles": 0,
        "months": 12
    },
    "discount": 25,
    "totalMaxDiscount": 100,
    "id": "10de0900-7751-43f7-a415-fec4fa835009",
    "type": "time_limited_absolute_product_discount",
    "promotionName": "my promo",
    "lockingStatus": "open"
}

Time-Limited Absolute Item Discount

Granularity: Item
Condition: Time-Limited
Discount Model: Absolute

Schema:

---
type: "object"
properties:
  description:
    type: "string"
  discount:
    type: "number"
  id:
    type: "string"
  lockingStatus:
    type: "string"
    description: "OPEN, CLOSE_TO_DELETIONS, CLOSE_TO_CHANGES, DEPRECATED"
  promotionName:
    type: "string"
  promotionTimeLimit:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  targetProductItemId:
    type: "string"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
    description: "must be time_limited_absolute_item_discount"

Example:
In the example below we create a new promotion which is limited to 12 months since the moment it is applied to a customer. The promotion 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 promotion was applied.

{
    "targetProductItemId": "552a8bf2-864e-4f89-87b0-0962aaec5cdf",
    "promotionTimeLimit": {
        "cycles": 0,
        "months": 12
    },
    "discount": 10,
    "totalMaxDiscount": 500,
    "id": "9d6cb505-bc9a-4ada-8f27-5b39a39428aa",
    "type": "time_limited_absolute_item_discount",
    "promotionName": "my promo",
    "lockingStatus": "open"
}

Time-Limited Relative Product Discount

Granularity: Product
Condition: Time-Limited
Discount Model: Relative

Schema:

---
type: "object"
properties:
  cycleMaxDiscount:
    type: "number"
  description:
    type: "string"
  discountRatio:
    type: "number"
  id:
    type: "string"
  lockingStatus:
    type: "string"
    description: "OPEN, CLOSE_TO_DELETIONS, CLOSE_TO_CHANGES, DEPRECATED"
  promotionName:
    type: "string"
  promotionTimeLimit:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  targetProductId:
    type: "string"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
    description: "must be time_limited_relative_product_discount"

Example:
In the example below we create a new promotion which is limited to 18 billing cycles since the moment it is applied to a customer. The promotion itself gives a 10% discount on the top of the entire bill (up to $100 for all consecutive invoices since the promotion was applied).

{
    "targetProductId": "feb90ba8-58a5-4c93-862a-8befc88c31c7",
    "promotionTimeLimit": {
        "cycles": 18,
        "months": 0
    },
    "discountRatio": 0.1,
    "totalMaxDiscount": 100,
    "cycleMaxDiscount": null,
    "id": "db859149-56e5-4b35-8946-96efdff0c7f9",
    "type": "time_limited_relative_product_discount",
    "promotionName": "my promo",
    "lockingStatus": "open"
}

Time-Limited Relative Item Discount

Granularity: Item
Condition: Time-Limited
Discount Model: Relative

Schema:

---
type: "object"
properties:
  cycleMaxDiscount:
    type: "number"
  description:
    type: "string"
  discountRatio:
    type: "number"
  id:
    type: "string"
  lockingStatus:
    type: "string"
    description: "OPEN, CLOSE_TO_DELETIONS, CLOSE_TO_CHANGES, DEPRECATED"
  promotionName:
    type: "string"
  promotionTimeLimit:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  targetProductItemId:
    type: "string"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
    description: "must be time_limited_relative_item_discount"

Example:
In the example below we create a new promotion which is limited to 18 billing cycles since the moment it is applied to a customer. The promotion 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 promotion was applied).

{
    "targetProductItemId": "acde888f-7720-4138-918d-f9442febc96e",
    "promotionTimeLimit": {
        "cycles": 18,
        "months": 0
    },
    "discountRatio": 0.1,
    "totalMaxDiscount": 100,
    "cycleMaxDiscount": null,
    "id": "768dbdb4-932b-430b-be8c-aae3a9a2c1ca",
    "type": "time_limited_relative_item_discount",
    "promotionName": "my promo",
    "lockingStatus": "open"
}

Time-Limited Tiered Absolute Product Discount

Granularity: Product
Condition: Time-Limited
Discount Model: Tiered-Absolute

Schema:

---
type: "object"
properties:
  description:
    type: "string"
  discountMap:
    type: "object"
        additionalProperties:
        type: "number"
  id:
    type: "string"
  lockingStatus:
    type: "string"
    description: "OPEN, CLOSE_TO_DELETIONS, CLOSE_TO_CHANGES, DEPRECATED"
  measure:
    type: "object"
  promotionName:
    type: "string"
  promotionTimeLimit:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  targetProductId:
    type: "string"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
        description: "must be time_limited_tiered_absolute_product_discount"

Example:
In the example below we create a new promotion which is not limited in time. The promotion 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.

{
    "targetProductId": "1",
    "promotionTimeLimit": {
        "cycles": 0,
        "months": 0
    },
    "discountMap": {
        "1": 1,
        "10": 2
    },
    "totalMaxDiscount": null,
    "id": "c58986fc-ee9f-427c-8163-3695c9dba0e1",
    "type": "time_limited_tiered_absolute_product_discount",
    "promotionName": "my promo",
    "lockingStatus": "open"
}

Time-Limited Tiered Absolute Item Discount

Granularity: Item
Condition: Time-Limited
Discount Model: Tiered-Absolute

Schema:

---
type: "object"
properties:
  description:
    type: "string"
  discountMap:
    type: "object"
        additionalProperties:
        type: "number"
  id:
    type: "string"
  lockingStatus:
    type: "string"
    description: "OPEN, CLOSE_TO_DELETIONS, CLOSE_TO_CHANGES, DEPRECATED"
  measure:
    type: "object"
  promotionName:
    type: "string"
  promotionTimeLimit:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  targetProductItemId:
    type: "string"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
    description: "must be time_limited_tiered_absolute_item_discount"

Example:
In the example below we create a new promotion which is not limited in time. The promotion 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.

{
    "targetProductItemId": "2d59a1d5-31d7-409d-9d78-843f31eb3e08",
    "promotionTimeLimit": {
        "cycles": 0,
        "months": 0
    },
    "discountMap": {
        "1": 1,
        "10": 2
    },
    "totalMaxDiscount": null,
    "id": "4f7c999d-213f-4472-87c1-1b26da690338",
    "type": "time_limited_tiered_absolute_item_discount",
    "promotionName": "my promo",
    "lockingStatus": "open"
}

Time-Limited Tiered Relative Product Discount

Granularity: Product
Condition: Time-Limited
Discount Model: Tiered-Absolute

Schema:

---
type: "object"
properties:
  cycleMaxDiscount:
    type: "number"
  description:
    type: "string"
  discountCalculationStrategy:
    type: "string"
    description: "STEP_FUNCTION, CHOOSE_SINGLE_TIER"
  id:
    type: "string"
  lockingStatus:
    type: "string"
    description: "OPEN, CLOSE_TO_DELETIONS, CLOSE_TO_CHANGES, DEPRECATED"
  priceToDiscountMap:
    type: "object"
        additionalProperties:
        type: "number"
  promotionName:
    type: "string"
  promotionTimeLimit:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  targetProductId:
    type: "string"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
    description: "must be time_limited_tiered_relative_product_discount"

Example:
In the example below we create a new promotion which is limited to 18 billing cycles. The promotion 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 promotion. The discount itself is calculated using the "step_function" method mentioned above.

{
    "targetProductId": "1",
    "promotionTimeLimit": {
        "cycles": 18,
        "months": 0
    },
    "priceToDiscountMap": {
        "0": 0.1,
        "10": 0.2
    },
    "discountCalculationStrategy": "step_function",
    "totalMaxDiscount": 100,
    "cycleMaxDiscount": 19,
    "id": "67a63178-cdd4-48f6-a305-2038033abd9a",
    "type": "time_limited_tiered_relative_product_discount",
    "promotionName": "my promo",
    "lockingStatus": "open"
}

Time-Limited Tiered Relative Item Discount

Granularity: Item
Condition: Time-Limited
Discount Model: Tiered-Absolute

Schema:

---
type: "object"
properties:
  cycleMaxDiscount:
    type: "number"
  description:
    type: "string"
  discountCalculationStrategy:
    type: "string"
    description: "STEP_FUNCTION, CHOOSE_SINGLE_TIER"
  id:
    type: "string"
  lastUpdateTimeInMillis:
    type: "integer"
  lockingStatus:
    type: "string"
    description: "OPEN, CLOSE_TO_DELETIONS, CLOSE_TO_CHANGES, DEPRECATED"
  priceToDiscountMap:
    type: "object"
        additionalProperties:
        type: "number"
  promotionName:
    type: "string"
  promotionTimeLimit:
    type: "object"
    properties:
      cycles:
        type: "integer"
      months:
        type: "integer"
  targetProductItemId:
    type: "string"
  totalMaxDiscount:
    type: "number"
  type:
    type: "string"
    description: "must be time_limited_tiered_relative_item_discount"

Example:
In the example below we create a new promotion which is limited to 18 billing cycles. The promotion 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 promotion. The discount itself is calculated using the "step_function" method mentioned above.

{
    "targetProductItemId": "806fdb8e-5bce-4b24-b6ce-ab37ef857e89",
    "promotionTimeLimit": {
        "cycles": 18,
        "months": 0
    },
    "priceToDiscountMap": {
        "0": 0.1,
        "10": 0.2
    },
    "discountCalculationStrategy": "step_function",
    "totalMaxDiscount": 100,
    "cycleMaxDiscount": 25,
    "id": "4ba106b9-2ef5-48b5-bc13-24dcf6cd635d",
    "type": "time_limited_tiered_relative_item_discount",
    "promotionName": "my promo",
    "lockingStatus": "open"
}

Did this page help you?