Try our conversational search powered by Generative AI!

ARCHIVED This content is retired and no longer maintained. See the latest version here.

Recommended reading 

Creating a custom promotion (discount)

When creating a new promotion type, you need the following:

  • PromotionData - the definition of the promotion, that is, the metadata needed to correctly run the promotion.
  • A processor - responsible for evaluating if a promotion can be applied on an order group.
  • A result - to be returned from the processor. The result is responsible for indicating if a reward should be applied, and the logic for applying the reward. The reward is the benefits that should be applied to an order.


When creating a promotion, you first need a PromotionData. It should contain all properties needed to evaluate an order group and apply a reward. For example, it contains applicable entries and discount size. Add to PromotionData any property that should be edited by a marketer setting up promotions. Basic metadata properties, like name and valid dates, are provided from the base class.

PromotionData comes in three flavors, see below. When creating a promotion, you should inherit from one of these, never from PromotionData directly.

  • EntryPromotion - applies reward to a specific entry.
  • OrderPromotion - applies reward to the full order.
  • ShippingPromotion - applies reward to the order's shipping cost.

IPromotionProcessor and PromotionProcessorBase

Once you have promotion data, you need to make a processor. The processor is responsible for evaluating if a promotion should apply a reward to an order group. You can implement the IPromotionProcessor interface directly, but the recommended way is to inherit from the abstract class PromotionProcessorBase<TPromotionData>. TPromotionData in this case should be the promotion data you created in the step above.

PromotionProcessorBase has one abstract method that needs to be implemented, Evaluate. The method is supplied with an IOrderGroup, which would be the cart, and a PromotionData and is responsible to evaluate if a reward should apply. The Evaluate method should return an IPromotionResult with information about if and how the promotion should be applied.


A promotion result should contain this:

  • An ApplyReward method that applies the reward to an IOrderGroup and returns a list of PromotionInformation that describes any applied rewards.
  • A Description that describes the promotion.
  • A Status flag, indicating if the promotion is not, somewhat, almost, or fully fulfilled.


The ApplyReward method should return a collection of PromotionInformation objects for each applied reward. A PromotionInformation has these properties:

  • PromotionInformationId - primary key of object read only
  • Description - a readable description of what reward was applied.
  • SavedAmount - the amount of money, if any, that was saved by applying this reward.
  • LineItem - the line item, if any, that was affected.
  • IsActive - whether the promotion was applied to the order

Adding help text for custom groups

For campaigns and promotions, you can add help texts in the form UI to guide users. To add help text for a custom group on the campaign or promotion form, add a Display attribute with GroupName property set to the name of a specific node within the “groups” section in the resource files.


[Display(GroupName = "MyNewGroup")]
        public virtual decimal Money { get; set; }

The resource file will look like this:

          <help>This is help text for my new group</help>

Adding money collections to your promotion

Your promotion may need a collection of currencies and amounts as part of your condition evaluation or reward logic. To achieve this, add an IList<Money> property to your custom promotion class. When used on a promotion type, such a Money collection is tightly coupled with the currencies available on the parent campaign.

Initially, any existing currencies related the promotion's campaign market added to the collection have the amount of zero. Changing the campaign market also changes available currencies in the property. Consider this when developing discount processors, because you must decide the desired behavior when one, or even all, amounts are set to zero.

Do you find this information helpful? Please log in to provide feedback.

Last updated: May 25, 2015

Recommended reading