K Khan
Jul 24, 2016
(2 votes)

Custom Promotions - eCommerce developer handout


Define metadata of Criteria and Reward. It should contain all properties needed to evaluate an order and apply a reward. For example, a PromotionData contains entries to which the promotion applies and the discount. Add to this type any property that a marketer should edit when setting up a promotion.  The base class provides basic metadata properties, such as name and valid dates.

  • EntryPromotion. Applies reward to a specific entry. Inherited from PromotionData
  • OrderPromotion. Applies reward to full order. Inherited from PromotionData
  • ShippingPromotion. Applies reward to order's shipping cost. Inherited from PromotionData

Note: Use one of those related class to create custom promotion meta data.


Decorate meta data properties like as colours to communicate meaning of properties to editors.
Colors make it easier to communicate what each property means in the UI. By adding the PromotionRegion attribute to a promotion property, it is marked for being included in the connection to the description. You also can use the PromotionRegion attribute on a block property, to connect properties in a block to the same part of the promotion description.


Promotion reward that can be either percentage of the purchase amount, or an absolute amount of for a given currency.

Localization in promotions

Like all content types, it is possible to translate the name and description by adding an element in the XML file whose name matches the content type. You can use a new formdescription sub-element to connect properties with the description. By adding "{regionname}some text{/}" in the text, the part "some text" gets the color matching that region. Both{regionname} and {/} are removed before the UI displays the description. e.g. For
[ContentType(GUID = "76EBFEFF-2CFB-42F2-B4A3-EA5EA5A41515")]

public class CustomPromotion : EntryPromotion

XML will be like

<name>My custom promotion</name>
<create see="/contenttypes/custompromotion/name" />
<description>Buy at least X items from categories/entries and get a % discount on the cheapest item.</description>
<formdescription>Buy {condition} at least X items from categories/entries{/} and get {reward}a % discount{/} on the cheapest item.</formdescription>


Very important object that is passed into promotion processors and reward applicators, which contains discount information about the affected items. Contains properties like Entry Prices, Shipment Prices, Current order Form Sub Total, Order Form and Order Group etc.

Promotion Processor

A class that evaluates if a promotion should apply a reward to an order and returns a Reward description from Promotion engine.


Abstract class inherited from IpromotionProcessor, You can inherit this class to build promotion processor but the recommended way is to inherit from the abstract EntryPromotionProcessorBase<TEntryPromotion>,  OrderPromotionProcessorBase<TOrderPromotion>, or  ShippingPromotionProcessorBase<TShippingPromotion> depending on the type of promotion being created.


Object that contains information about if and how a reward is applied. Importantant properties are

  • List of Redemption Description - one for each of the maximum amount of redemptions that could be applied to the current order
  • Reward Type - Depending on the type, the discount value is read from the properties UnitDiscountPercentage orQuantity
  • Status(Fulfilment status) - Orders with status Fulfilled will be honoured by promotion engine. (NotFulfilled, PartiallyFulfilled, Fulfilled, CouponCodeRequired, Excluded, VisitorGroupRequired, RedemptionLimitReached, InvalidCoupon, InvalidCombination, MissingVisitorGroup, NoRedemptionRemaining)


Describes one redemption of a reward. Its primary goal is to identify the objects to which the redemption should apply. Other than that, the RedemptionDescription also says how much this redemption saves on the order, and has a status flag that is set if the promotion engine (for some reason) decides not to apply this redemption. Most commonly, that is because a redemption limit was reached.


List of Affected entries for redemptions, if its an entry level promotion.


List of Affected shipments for redemptions, if its a shipment level promotion.


List of Affected orders for redemptions, if its and order level promotion.


defines which affected entries, received from the price matrix, should receive a discount. The method has two parameters: skip and take. The example "Buy 3, get the cheapest for free" should make the call SetDiscountRange(2, 1), which skips the first two items, and gives the discount (free) to the third. If all items get the discount, e.g. there is 20% off all items, SetDiscountRange does not have to be called.


  • A promotion may need a collection of currencies and amounts as part of the condition evaluation or reward logic. To achieve this, add an IList<Money> property to the custom promotion class. The same applies to the MonetaryReward type.
  • To include help text for custom groups on a campaign or promotion form, add the Display attribute with the GroupNameproperty set to the name of a specific node within the <groups> section in the resource files. The groups sections are content-type specific, so should be placed under <contenttypes> node for your specific type.
    [Display(GroupName = "MyNewGroup")]
    public virtual decimal Money { get; set; }
    The resource file will be like this
            <help>This is help text for my new group</help>
  • use base processor's method CreateRedemptionDescription
  • RewardDescription.CreateMoneyOrPercentageRewardDescription  can be used  to retrieve reward type.
  • Only promotions with the status Fulfilled will have their rewards applied.




Jul 24, 2016


Please login to comment.
Latest blogs
Plug-in manager is back in CMS 12

Plug-in manager is back in the UI, what is it and how can i use it?

Luc Gosso (MVP) | Oct 6, 2022 | Syndicated blog

Display Child Pages in Content Delivery API Response

The below example will implement an instance of IContentConverterProvider to customise the serialisation of PageData and output child pages in the...

Minesh Shah (Netcel) | Oct 4, 2022

Bring the Report Center back in Optimizely CMS 12

The Report Center has been a part of Optimizely CMS since its first debut in version 5R2 in 2008, but in CMS 12, it's removed! Don't despair! Make...

Tomas Hensrud Gulla | Oct 4, 2022 | Syndicated blog

Customizing Property Lists in Optimizely CMS

Generic property lists is a cool editorial feature that has gained a lot of popularity - in spite of still being unsupported (officially). But if y...

Allan Thraen | Oct 2, 2022 | Syndicated blog