Predicate language

Predicates are boolean expressions used to configure commerce rules. Thor compiles them as typed Dynamic LINQ expressions when a rule is created or updated, then evaluates them against runtime commerce data.

Predicates are not the same language as the query search syntax. Search strings filter Elasticsearch documents; predicates read a fixed, strongly typed object and must return true or false.

Choose the correct context

Predicate locationExpression rootDetailed reference
Cart discount, shipping method or rate, payment gatewayThe full cart: customer, subtotal, shipping_address, line_items, and moreCart predicates
A cart discount’s line-item targetOne line item: product, variant, quantity, amount, and moreLine-item target predicates
Product discountOne currently active product-variant price record and its product contextProduct predicates

The object shape is part of the language. A cart expression such as line_items.any(...) is invalid as a line-item target because the target already evaluates one line item at a time.

Common syntax

The supported building blocks used by Thor’s predicate contexts are:

  • comparisons: ==, !=, >, >=, <, <=
  • boolean logic: &&, ||, !
  • grouping with parentheses
  • collection membership with .Contains(value)
  • collection matching with .any(item => expression)
  • collection size with .count()
  • string matching with methods such as .Contains(value)
  • literals such as strings, integers, decimals, true, false, and null

Property names are snake_case. Use ==, not JavaScript’s ===. String comparisons are ordinal and case-sensitive, so use the exact value stored by Thor. IDs, ISO currency codes, and country codes should be copied from API data instead of reconstructed.

Evaluation rules

  • && binds more tightly than ||; use parentheses to make mixed expressions obvious.
  • Collection lambdas can inspect the current item, for example li => li.product.tags.Contains("sale").
  • Guard nullable objects before accessing a nested field. Shipping and billing addresses can be null; product-price context IDs can also be absent.
  • Cart and product predicates normalize an empty predicate to an always-true expression. A line-item target should still be given an explicit predicate such as true.
  • Monetary cent_amount and product price.amount values are integer minor units. Predicate evaluation does not convert currencies for you.
  • A syntactically valid predicate can still never match if it compares the wrong currency, context ID, casing, or unit.

Authoring workflow

  1. Pick the rule and therefore the correct predicate context.
  2. Start with one equality check against an ID or code returned by the API.
  3. Add amount, address, or collection clauses and group mixed boolean logic.
  4. Save through the Admin API so Thor validates the expression and its property names.
  5. Exercise positive and negative cases, including anonymous customers, missing addresses, multiple customer groups, multiple line items, and contextual prices.

The detailed cart and product references list every available field and provide copyable recipes.