Area: Episerver B2B Commerce

Creating a custom Rule Type option (Criteria Type)

Recommended reading 

In this example, the website needs to provide a discount to customers who have the default payment method set to ACH or Credit Card. This requires building a custom derived criteriatype class that will serve as the rule type option for promotions.

This example will use a LookupObject to populate the simple value for the Terms Code when configuring the Rule Type Option in the Admin Console.


  • The payment methods of ACH and CC must be configured in the Admin console
  • The customers must have the Default Payment Method configured on their account
  • Shipping carriers and services must be configured in order to complete the checkout process


  1. In the Epi B2B Commerce Web project in Visual Studio create a new folder called Extensions.
  2. Add a new Class called CriteriaTypeOrderTermsCode
  3. Derive from the base class CriteriaTypeBase and decorate the class with the Dependency attribute with a name of OrderTermsCode.
public class CriteriaTypeOrderTermsCode : CriteriaTypeBase

  1. Override the LookupObject and CriteriaObject properties. These are two important overrides to note as the PaymentMethod will populate the drop down in the Admin Console and the CustomerOrder will be the object this rule operates on.
public override string LookupObject => nameof(PaymentMethod);

public override string CriteriaObject => nameof(CustomerOrder);

  1. Override the remaining abstract properties as follows:
/// <summary>The requires criteria object.</summary>
public override bool RequiresCriteriaObject => false;

/// <summary>The requires criteria property.</summary>
public override bool RequiresCriteriaProperty => false;

/// <summary>The requires criteria value.</summary>
public override bool RequiresCriteriaValue => false;

/// <summary>The criteria value label.</summary>
public override string CriteriaValueLabel => string.Empty;

/// <summary>The requires value type.</summary>
public override bool RequiresValueType => false;

/// <summary>The requires geocode.</summary>
public override bool RequiresGeocode => false;

  1. The Terms Code will validate whether the customer has a particular Terms Code or not. Override and add the equals and not equals rule type comparison operators to the ValidRuleClauseComparisonOperators collection.
/// <summary>The valid rule clause comparison operators.</summary>
public override IList<RuleClauseComparisonOperator> ValidRuleClauseComparisonOperators => new List<RuleClauseComparisonOperator>

  1. Next define the parameters that can be configured using the Admin Console. In this example it will use a "Select Based On" parameter to choose between the equals or not equals comparison operators. It will also use a Terms Code value that will be selected from a drop down of all the valid options. This is where the LookupObject is leveraged. Override the ParameterDescriptions property and add the two dictionary values.
/// <summary>The parameter descriptions.</summary>
public override Dictionary<string, CriteriaTypeParameter> ParameterDescriptions => new Dictionary<string, CriteriaTypeParameter>
    { nameof(RuleClause.ComparisonOperator), new CriteriaTypeParameter
            Label = "Select Based On",
            PossibleValues = this.ValidRuleClauseComparisonOperators.Select(x => x.ToString()).ToArray()
    { nameof(RuleClause.SimpleValue), new CriteriaTypeParameter { Label = "Terms Code", LookupField = true } }

  1. Override the Validate method which will handle the logic of the configuration defined and selected. The following will validate the argument is a CustomerOrder, as configured in the CriteriaObject property, and return true or false based on the value configured to the customer.
/// <summary>The validate.</summary>
/// <param name="ruleClause">The rule clause.</param>
/// <param name="argument">The argument.</param>
/// <returns>The <see cref="bool"/>.</returns>
public override bool Validate(RuleClause ruleClause, object argument)

    if (!(argument is CustomerOrder))
        throw new ArgumentException("argument must be of type CustomerOrder");

    var customerOrder = (CustomerOrder)argument;

    if (ruleClause.ComparisonOperator == RuleClauseComparisonOperator.Equals.ToString())
        if (ruleClause.SimpleValue == customerOrder.TermsCode)
            return true;
            return false;

    if (ruleClause.ComparisonOperator == RuleClauseComparisonOperator.NotEquals.ToString())
        if (ruleClause.SimpleValue != customerOrder.TermsCode)
            return true;
            return false;

    throw new ArgumentException(nameof(ruleClause.ComparisonOperator) + " is not valid, it was " + ruleClause.ComparisonOperator);

  1. Build the solution and log into the Admin Console.
  2. Navigate to Administration > System > Rule Types, and edit the Promotion Rule Type.
  3. Navigate to the Rule Options finger tab and click the Add Rule Type button.
  4. Configure the new Rule Type Option as follows:
    • Description: Terms Code
    • Criteria Type: Order Terms Code
    • Criteria Object: CustomerOrder
  5. Save the changes.
  6. Navigate to Marketing > Promotions and create two new promotions. Create one promotion with the Terms Code rule using the ACH terms code value and equals operator. Create the other promotion rule with the Terms Code rule using CC as the terms code value and equals operator. For both, the result should be Percentage off the order. Experiment with these values where appropriate. For example, set the ACH terms code result to 25% off the order and set the CC terms code result to 5% off the order.
  7. Save the changes.
  8. Navigate to Websites and edit the existing Epi B2B Commerce website.
  9. Navigate to the Promotions finger tab and assign the two Promotions to the website.
  10. Finally, navigate to the Settings finger tab and set the AllowCreditcardPaymentMethod as false.
  11. Save the changes and navigate to the website site.
  12. Complete the checkout process signed in as a customer with ACH and note the discount applied on the order.
Do you find this information helpful? Please log in to provide feedback.

Last updated: Dec 11, 2020

Recommended reading