Discounts and Promotions
Build Any Discount Model
54min
high level introduction amberflo is designed around flexible, extensible data structures that support a wide range of billing scenarios this flexibility allows you to define and apply any type of meter, pricing logic, rewards system, or discount model to match your business needs this document focuses specifically on the promotions model , and covers the following the core discount data structure the generic discount , which is highly flexible and suitable for advanced use cases the discount templates , which offer a simpler, more guided configuration experience the discount structure at a high level, every discount in amberflo consists of four main components granularity – defines the level at which the discount is applied, such as invoice wide or per product item condition – specifies when the discount should apply, based on attributes like customer tags or dimension values discount model – determines how the discount is calculated, such as a percentage, fixed amount, or tiered structure measure – indicates what metric the discount is applied to (e g invoice total, usage quantity, or cost for a specific item) 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 granularity in usage based pricing, an invoice often includes multiple pricing components these can range from high level totals to highly detailed line items the total invoice price , before any discounts are applied the total usage price , which is the sum of all item level usage charges the price for a specific invoiced item , which in turn may be broken down further by dimension variants the total fixed fees , made up of individual fee line items granularity refers to the specific target of a discount within this structure it determines which part of the invoice the discount is applied to amberflo currently supports two types of granularity product (or plan) – applies the discount to the total invoice amount item – applies the discount to the total cost of a specific invoiced item (for example, a specific product or service) support for more granular targets may be added in the future this could include applying discounts to the total usage price across all items a particular fixed fee a specific usage variant defined by dimension values the key point is that every part of the invoice can potentially be targeted by a discount, and the granularity setting determines where the discount is applied condition the condition defines the rules that determine when and to whom a discount can be applied it helps answer two key questions can we apply the discount? this checks whether the discount is valid for the customer it may depend on factors like customer tags, traits, or whether the customer already had the discount applied in a previous billing cycle can the discount be used at this time? even if the discount is valid for the customer, there may be constraints that prevent it from applying to the current invoice this could include expiration dates, usage limits, or timing related rules conditions help ensure that discounts are applied intentionally and contextually , preventing misuse or misapplication across billing cycles below is a diagram describing the existing discount conditions time limited condition this condition limits a discount for a specified number of billing cycles , a certain number of months , or the mix of both if neither cycles nor months is provided, or if promotiontimelimit is omitted entirely, the discount will have no time limit and will remain active indefinitely 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 discount as long as the customer is on same plan as the plan used when applying the discount schema \ type "object" properties type type "string" 	 description "must be same plan" after product price threshold condition this condition tells the system to begin applying a discount only after the customer has reached a specified product level billing threshold the threshold is calculated as the accumulated total of the customer’s current and previous invoices, based on the time window defined in the requiredhistory setting of the condition for example, you can configure a discount to activate once a customer has spent $1,000 , regardless of whether it took one billing cycle or several to reach that amount this allows for flexible, spend based discounting that rewards continued or cumulative usage over time 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 condition doesn’t restrict whether a discount can be applied instead, it simply instructs the system to delay the start of the discount until the next billing cycle following its assignment once the discount is assigned to a customer, it will not affect the current invoice, but will be automatically applied beginning with the next month's billing this condition is useful when you want to schedule a discount in advance without applying it retroactively or mid cycle \ 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" discount model this is the actual discount model we apply on the current invoice we currently support the following models model with max this is not a standalone discount model, but rather a base structure used by several existing models in the system it includes optional limits that control how much discount can be applied over time a model with max allows you to define a total maximum discount applied across all billing cycles since the discount began a maximum discount per billing cycle these optional caps provide a way to ensure that discount amounts stay within expected boundaries, regardless of usage or billing frequency absolute the absolute discount model applies a fixed , constant amount to the bill the discount can be scoped to either a specific product item , or the entire product bill , depending on the granularity setting this model is useful for straightforward scenarios, such as subtracting $500 from a customer’s invoice total 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 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 \ 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 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 \ 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 for any total price between $50 to $100 $10 for any total price of $100 or higher tiered relative the tiered relative model provides a more flexible way to apply percentage based discounts it supports two distinct discounting strategies choose single tier in this approach, the system evaluates the total discountable price against a set of predefined tiers once the appropriate tier is determined, the corresponding discount rate is applied to the entire amount this method is straightforward and applies a single percentage based on which threshold the total price falls into step function this strategy works similarly to how income taxes are calculated the total discountable price is split into intervals , and each interval is discounted separately according to its assigned rate each range starts at a defined point (labeled as ai), and the system applies the matching percentage to each portion of the price within its respective tier 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 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 diving into the different discount object types, it's important to understand one final, advanced concept the measure a discount model typically operates on the price , but in more advanced use cases, it can also operate on the usage itself in these cases, the discount is calculated based on the number of invoiced units, using either the average item price or item specific pricing logic this flexibility is key when applying precise, usage based discounts rather than a flat amount off the total why do we need the measure consider a scenario where you want to apply an absolute discount to a specific item invoice that invoice will usually include the total usage amount for the item the total price charged for that usage you have several ways to define how the discount should be applied totalprice a flat discount amount (e g , $100) off the total item invoice this could be scoped at either the product item level or the full product level, depending on granularity perunit a discount applied to each unit of usage for instance, $0 01 off per unit perunitbatch a discount applied per batch of usage—for example, $5 off for every 100 units consumed this allows for very specific and scalable discount models that align with how your product is used and billed 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 discounts generic discount models are the most advanced and flexible way to define promotions in amberflo these are only available through the api and are designed for cases where none of the standard templates meet your specific requirements because generic discounts require more detailed configuration and validation, we recommend first checking whether a template based promotion can achieve what you need use generic promotions only when more control or customization is necessary we currently support two types of generic models generic product promotion 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 this is a straightforward example using granularity product condition time limited model relative (percentage based discount) this is functionally equivalent to the "time limited relative product discount" template, but implemented manually through the generic model structure { "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 this example shows the flexibility of generic models a relative discount applied at the product level condition 1 the customer must have accumulated at least $10 in product charges over the past 6 months (including the current month) condition 2 the discount is only valid for 18 months after it was first applied while this level of complexity is less common in practice, it illustrates how generic promotions allow for highly tailored business logic { "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 } generic item promotion the genericitempromotion model allows you to configure highly specific item level discounts using advanced logic like genericproductpromotion , this model is only available via the api and is intended for cases where template based configurations are insufficient schema \ type "object" properties condition type "object" description type "string" dimensionconstraintmap type "object" description "a map of dimension key to value (string to string) indicating that this promotion can only be applied against usage that includes the given dimension values " additionalproperties 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 this example defines a discount with granularity item condition time limited model relative (a percentage based discount) functionally, this is the item level equivalent of the "time limited relative product discount" template { "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 this builds on the first example but adds a constraint the discount only applies to usage that matches the following dimension values cloudprovider = aws region = us west 2 this setup ensures the discount is only applied to usage tied to specific resource attributes { "targetitemid" "58e0a665 5244 4d01 8e1e c0a7a72f169a", "promotiontype" "discount", "condition" { "type" "time limited", "requiredhistory" { "cycles" 0, "months" 1 } }, "dimensionconstraintmap" { "region" "us west 2", "cloudprovider" "aws" }, "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 3 this example demonstrates the full flexibility of the schema by combining multiple conditions the total item level charges must be at least $10 over the last 5 invoices the total product level charges must be at least $500 over the same 5 invoices the pricing plan must remain unchanged during the discount period the discount expires 12 months after it is first applied while this level of complexity is not common, it illustrates how generic item level promotions can be used to enforce detailed billing and usage logic { "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 templates represent the most common and recurring discount patterns to simplify configuration, amberflo provides pre defined templates that wrap these patterns into an easy to use structure each template reflects a standard use case that can be quickly customized without requiring manual configuration of advanced fields time limited absolute product discount granularity product condition time limited discount model absolute this template applies a fixed discount amount to the total product level invoice the discount is valid for a defined number of billing cycles or months, after which it expires automatically 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 this discount is valid for 12 months from the moment it is applied to a customer it targets the entire invoice total and provides a maximum of $25 off per invoice a cumulative maximum of $100 across all invoices while the discount is active { "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" dimensionconstraintmap type "object" additionalproperties 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 this discount is also limited to 12 months from the time it is applied it targets a single product item (identified as 552a8bf2 864e 4f89 87b0 0962aaec5cdf) and allows up to $10 off per invoice a total maximum of $50 over the life of the discount { "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 this case, the discount is active for 18 billing cycles from the point of application it gives the customer a 10% discount on the total invoice amount, with an upper limit of $100 total across all invoices during that period { "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" dimensionconstraintmap type "object" description "a map of dimension key to value (string to string) indicating that this promotion can only be applied against usage that includes the given dimension values " additionalproperties 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 this discount is active for 18 billing cycles after it is applied to a customer it gives a 10% discount on the usage cost of a specific item (acde888f 7720 4138 918d f9442febc96e) with a total cap of $100 across all invoices while the discount is active { "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 acrossbillingperiods type "boolean" description "if true then the tier level discount will be detemined using the sum of all invoices since the promotion was applied " 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 1 this discount is not time limited it applies to the entire product level bill using a tiered structure $1 discount if the invoice total reaches $1 $2 discount if the invoice total reaches $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" } example 2 this version is limited to 3 months from the time it is applied the discount uses the same tiered structure $1 discount for the first $1 spent per invoice $2 discount if the total across all invoices since the discount was applied reaches $10 or more { "targetproductid" "1", "acrossbillingperiods" true, "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 acrossbillingperiods type "boolean" description "if true then the tier level discount will be detemined using the sum of all invoices since the promotion was applied " description type "string" dimensionconstraintmap type "object" description "a map of dimension key to value (string to string) indicating that this promotion can only be applied against usage that includes the given dimension values " additionalproperties 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 this discount is not limited in time it applies to the usage bill of item 2d59a1d5 31d7 409d 9d78 843f31eb3e08 the tiered discount provides $1 off if the invoice total for the item reaches $1 $2 off if the invoice total reaches $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 acrossbillingperiods type "boolean" description "if true then the tier level discount will be detemined using the sum of all invoices since the promotion was applied " 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 this discount is valid for 18 billing cycles and applies to the entire invoice total it uses the step function method to calculate the discount 10% off the first $10 spent 20% off any amount beyond that the discount is capped at $19 per cycle and $100 in total over its lifetime { "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 acrossbillingperiods type "boolean" description "if true then the tier level discount will be detemined using the sum of all invoices since the promotion was applied " cyclemaxdiscount type "number" description type "string" dimensionconstraintmap type "object" description "a map of dimension key to value (string to string) indicating that this promotion can only be applied against usage that includes the given dimension values " additionalproperties 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 this discount is active for 18 billing cycles and targets the usage cost of item 806fdb8e 5bce 4b24 b6ce ab37ef857e89 like the previous example, it uses the step function method 10% off the first $10 spent 20% off any additional spend the discount is capped at $25 per cycle and $100 total during its active period { "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" }