> For the complete documentation index, see [llms.txt](https://eventx-hq.gitbook.io/knowledge-base/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://eventx-hq.gitbook.io/knowledge-base/registration-and-ticketing/ticketing-and-pricing/pricing-rule.md).

# Pricing Rule

## Setting Up Pricing Rules

Pricing rules allow organizers to override the order total with a custom fixed price, deduction, or percentage discount when specific conditions are met. Rules are evaluated in order, and the first matching rule is applied. A common use case is setting a flat fee for bundled ticket + add-on purchases (e.g., an early bird package).

### Accessing Pricing Rules

1. Go to your event.
2. Click on **Ticket & Add-On** in the sub-navigation.
3. Select the **Pricing Rules** tab.

![](/files/w9LRVn0e6rCnNSXCjgBg)

If no pricing rules have been configured yet, the page will show an empty state with an **Add Pricing Rules** button.

![](/files/jERVg2IdaT7GGWE8GxuG)

### Creating a Pricing Rule

1. Click **Add Pricing Rules** to enter the editor.

![](/files/bOkRyGBxnqX54ZY0ZfTj)

2. Click **Add New Rule** to create your first rule.

![](/files/jNGZZdsWSSWjeX9iqRkD)

3. Enter a **Rule Name** to identify the rule.
4. Set the **Fixed Price** — this will be the new order total when the rule is matched.

**Note:** The fixed price must be at least the payment gateway minimum charge for your event's currency (e.g., HKD 6.00). A notice at the top of the editor shows the minimum for your event.

![](/files/1hRIQfVQYsStrl8ZuF86)

### Adding Criteria

Each rule must have at least one criterion. A rule only applies when **all** of its criteria are met. Click **Add Criterion** to add another condition.

![](/files/BZIaN3nDMF7ooLDChzml)

Select the criterion type from the **Item** dropdown. The available types are:

![](/files/YIEJeI6nSxcRyqQQo6NI)

#### Total Price

Compares the order total (after any promo code discount) against a threshold.

1. Select **Total Price** as the item type.
2. Choose an **Operator**: Equal To, Not Equal To, Greater Than, Greater Than or Equal To, Less Than, or Less Than or Equal To.
3. Enter a **Value** for the comparison.

**Example:** To apply a fixed price when the order total exceeds HKD 500, set the operator to **Greater Than** and the value to **500**.

![](/files/TeiweD6mNa5FtdI1tOfG)

#### Ticket

Matches specific ticket types with optional minimum and maximum quantity ranges.

1. Select **Ticket** as the item type.
2. Choose one or more ticket types from the **Targets** multi-select dropdown.
3. Optionally set a **Min** and/or **Max** quantity — the rule matches when the total purchased quantity of the selected tickets falls within the range.

**Example:** Target the "VIP" ticket with a Min of 2 to apply pricing when at least 2 VIP tickets are purchased.

![](/files/kQc6xoZfsr6llok8tSkf)

#### Add-On

Matches specific add-on items with optional minimum and maximum quantity ranges.

1. Select **Add-On** as the item type.
2. Choose one or more add-ons from the **Targets** multi-select dropdown.
3. Optionally set a **Min** and/or **Max** quantity.

![](/files/I3WNSTTmqiXVqP6Wik0U)

#### Registration Form

Matches orders where the attendee is registering through a specific registration form.

1. Select **Registration Form** as the item type.
2. Choose a registration form from the **Targets** dropdown.

![](/files/jvNH92AF4YGdGaWa5obk)

#### Promo Code

Matches based on whether a promo code is applied (or not).

1. Select **Promo Code** as the item type.
2. Choose from the available options:
   * **Any Promo Code** — matches when any promo code is applied to the order.
   * **No Promo Code** — matches when no promo code is applied.
   * A specific promo code from the dropdown — matches only when that exact promo code is used.

![](/files/urL3y1qX2P6spDHb1nl2)

### Deleting a Criterion

Hover over the criterion row and click the delete button (trash icon). A rule must have at least one criterion — the delete button is hidden when only one criterion remains.

![](/files/r3QaMJSiGk2hUUe8JqCY)

### Deleting a Rule

Click the delete button (trash icon) on the rule card to remove the entire rule.

![](/files/hwe7exoQ0GMiQxSUjZTv)

### Reordering Rules

Rules are evaluated in order from top to bottom. The **first matching rule** is applied — subsequent rules are ignored even if they also match.

Drag and drop the rule cards to change the evaluation order.

![](/files/zOVFmoazqdvL93LzsjUJ)

### Saving Pricing Rules

Once you have configured your rules, click **Save** at the bottom of the page. The save replaces all existing rules at once — there is no partial save or draft mode.

![](/files/qcY44Mdui7ICDWfEqqyG)

If there are validation errors (e.g., a required field is missing, or the fixed price is below the minimum charge), an error message will appear and the save will be blocked.

![](/files/qbkdgOTNfniwQX2jMM75)

Click **Back** to return to the list view. If you have unsaved changes, a dialog will ask whether you want to discard them or stay and continue editing.

![](/files/GwxQzMiLY43UMOmu4mCV)

### Code Mode

The pricing rule editor supports a **Code Mode** toggle that lets you edit rules directly as JSON. This is useful for power users managing many rules, or for AI agents that need to programmatically construct and modify pricing rules.

Switch between **Form Mode** and **Code Mode** using the toggle at the top of the editor:

<figure><img src="/files/26PDvhWZpakx2xbjJThi" alt=""><figcaption></figcaption></figure>

In Code Mode, the left side shows a JSON editor and the right side shows the live form preview. Edits in either pane are reflected in the other. The JSON is validated in real-time — the **Save** button is disabled when the JSON is invalid.

On mobile, the code editor appears above the form preview.

#### JSON Schema

A pricing rules payload is an **array** of rule objects. Each rule has a `name`, an array of `criteria`, and a `result`.

```json
[
  {
    "name": "Early Bird Bundle",
    "criteria": [
      {
        "item": "totalPrice",
        "operator": "greaterThanOrEqualTo",
        "value": 500
      },
      {
        "item": "ticket",
        "targets": ["ticket-uuid-1", "ticket-uuid-2"],
        "min": 2
      }
    ],
    "result": {
      "type": "fixedPrice",
      "fixedPrice": 350
    }
  }
]
```

#### Criterion Reference

Each criterion has a required `item` field (one of the values below) and type-specific optional fields.

**`item` values:**

| `item`       | Description                                | Required fields     | Optional fields |
| ------------ | ------------------------------------------ | ------------------- | --------------- |
| `totalPrice` | Compare order total against a threshold    | `operator`, `value` | —               |
| `ticket`     | Match specific ticket types and quantities | `targets`           | `min`, `max`    |
| `addOn`      | Match specific add-ons and quantities      | `targets`           | `min`, `max`    |
| `regForm`    | Match a specific registration form         | `targets`           | —               |
| `promoCode`  | Match promo code usage                     | `targets`           | —               |

**`operator` values (for `totalPrice` only):**

| Operator               | Meaning             |
| ---------------------- | ------------------- |
| `equalTo`              | Order total = value |
| `notEqualTo`           | Order total ≠ value |
| `greaterThan`          | Order total > value |
| `greaterThanOrEqualTo` | Order total ≥ value |
| `lessThan`             | Order total < value |
| `lessThanOrEqualTo`    | Order total ≤ value |

**`targets` values:**

* For `ticket` and `addOn`: an array of UUID strings. Use the IDs from the ticket class / add-on list.
* For `regForm`: an array with exactly one UUID string (the registration form ID).
* For `promoCode`: an array of UUID strings, or a special single-entry array:
  * `["*"]` — matches when **any** promo code is applied
  * `[]` — matches when **no** promo code is applied

**`min` / `max` (for `ticket` and `addOn` only):**

Positive integers. `min` defaults to `undefined` (no lower bound). `max` defaults to `undefined` (no upper bound). Omit either field to leave the bound open.

#### Result Reference

Each rule has a `result` object with a `type` field.

| `type`                 | Description                                | Value field                  | Example                                                            |
| ---------------------- | ------------------------------------------ | ---------------------------- | ------------------------------------------------------------------ |
| `fixedPrice`           | Replace order total with a fixed amount    | `fixedPrice` (number)        | `{ "type": "fixedPrice", "fixedPrice": 350 }`                      |
| `subtractedAmount`     | Deduct a fixed amount from the order total | `subtractedAmount` (number)  | `{ "type": "subtractedAmount", "subtractedAmount": 50 }`           |
| `subtractedPercentage` | Deduct a percentage from the order total   | `subtractedPercentage` (0–1) | `{ "type": "subtractedPercentage", "subtractedPercentage": 0.15 }` |

The `subtractedPercentage` value is a decimal between `0` and `1` (e.g., `0.15` = 15%). In the Form Mode UI, this is displayed as a whole number percentage (e.g., `15`).

#### Criteria Examples by Type

**Total Price — order total ≥ HKD 500:**

```json
{ "item": "totalPrice", "operator": "greaterThanOrEqualTo", "value": 500 }
```

**Total Price — order total between HKD 100 and HKD 500:** *(use two criteria with the same rule)*

```json
{ "item": "totalPrice", "operator": "greaterThanOrEqualTo", "value": 100 },
{ "item": "totalPrice", "operator": "lessThanOrEqualTo", "value": 500 }
```

**Ticket — at least 2 VIP tickets:**

```json
{ "item": "ticket", "targets": ["vip-ticket-id"], "min": 2 }
```

**Ticket — exactly 1 of any selected ticket:**

```json
{ "item": "ticket", "targets": ["ticket-a", "ticket-b"], "min": 1, "max": 1 }
```

**Add-On — at least 1 workshop add-on:**

```json
{ "item": "addOn", "targets": ["workshop-addon-id"], "min": 1 }
```

**Registration Form — specific form:**

```json
{ "item": "regForm", "targets": ["regform-uuid"] }
```

**Promo Code — any promo code applied:**

```json
{ "item": "promoCode", "targets": ["*"] }
```

**Promo Code — no promo code applied:**

```json
{ "item": "promoCode", "targets": [] }
```

**Promo Code — specific code:**

```json
{ "item": "promoCode", "targets": ["promo-code-uuid"] }
```

#### Complete Rule Examples

**Fixed price bundle (ticket + add-on with minimum quantity):**

```json
{
  "name": "Workshop Bundle",
  "criteria": [
    { "item": "ticket", "targets": ["general-admission-id"], "min": 1 },
    { "item": "addOn", "targets": ["workshop-addon-id"], "min": 1 }
  ],
  "result": { "type": "fixedPrice", "fixedPrice": 800 }
}
```

**Early bird discount (total above threshold with promo code):**

```json
{
  "name": "Early Bird 15% Off",
  "criteria": [
    { "item": "totalPrice", "operator": "greaterThanOrEqualTo", "value": 500 },
    { "item": "promoCode", "targets": ["early-bird-promo-id"] }
  ],
  "result": { "type": "subtractedPercentage", "subtractedPercentage": 0.15 }
}
```

**VIP flat rate:**

```json
{
  "name": "VIP Flat Rate",
  "criteria": [
    { "item": "ticket", "targets": ["vip-ticket-id"], "min": 1 }
  ],
  "result": { "type": "fixedPrice", "fixedPrice": 1200 }
}
```

## How Pricing Rules Work

1. When an attendee submits an order, all pricing rules for the event are evaluated **in order** (top to bottom).
2. For each rule, every criterion is checked. All criteria must be satisfied (AND logic).
3. The first rule where **all** criteria match is applied — remaining rules are skipped.
4. The order total is adjusted according to the rule's result type — **Fixed Price** replaces the total, **Deduction** subtracts a fixed amount, and **Percentage** subtracts a percentage of the total. Individual item prices are scaled proportionally so their sum equals the final price.
5. If no rule matches, the standard price calculation is used.

**Note:** Pricing rules are evaluated **after** any promo code discount is applied. For example, if a promo code reduces the order total from HKD 600 to HKD 400, the Total Price criterion compares against HKD 400, not HKD 600.

## Pricing Rules in Manage Registration

When an attendee edits their add-ons through **Manage Registration**, how the pricing rule is applied depends on the **Pricing Rule Checking on Manage Registration** toggle in **Event Settings > General Settings**.

### When the Toggle Is On (Default)

The pricing rule is re-applied from scratch over the attendee's full add-on set (existing plus newly added). The attendee pays only the difference between the newly calculated total and the previously paid total.

* If the difference is positive, the attendee pays that amount at checkout.
* If the difference is zero or negative, nothing is charged and no refund is given.

The attendee's summary lists the **Existing add-ons** and the newly added add-ons separately.

### When the Toggle Is Off

The attendee keeps the pricing rule that applied at their original registration. Newly added add-ons that fall within that rule's targets stay free, while add-ons outside the targets are charged at their regular price.

**Note:** Free add-ons follow the same rules. If a pricing rule makes a free add-on billable, the attendee must complete the paid checkout step.

## On Registration Form

When a pricing rule is applied to an order, the attendee will see the rule name and the adjusted price on the order summary.

![](/files/4CY0cEjGa71sN0SZokMo)

The attendee does not need to take any action — the pricing rule is applied automatically based on the items in their cart and any promo code used.

## Remarks

1. Pricing rules are evaluated per event. Rules cannot be shared across multiple events.
2. If no rules are configured (or the rules array is empty), standard pricing applies with no modifications.
3. The save action replaces the entire ruleset. Deleting all rules and saving effectively disables pricing rules for the event.
4. The minimum charge is enforced server-side based on the event's payment currency. Contact support if the displayed minimum looks incorrect.

## Limitation

1. Only **one rule** can be applied per order (first-match-wins). It is not possible to stack multiple rules.
2. Pricing rules support **fixed price**, **deduction**, and **percentage-based discount** results. Per-item price overrides are not available.
3. There is no draft or version history — saving immediately activates the new rules.
4. The Registration Form criterion checks only the first attendee's registration form in orders with multiple attendees.
5. Pricing rules cannot be set to expire on a specific date. To deactivate a rule, delete it and save.
6. The fixed price must be paid in the event's payment currency. Currency conversion is not applied.

## Checking Sequences

Here are the checking sequences in an Order

1. Ticket logics (min, max)
2. Addon and addon Group logics (min, max)
3. Promo Code
4. System try to Match the Pricing Rule
   1. Rules are evaluated in order. First matching rule applied.

## Related Articles

* [Ticketing Setup](https://eventx-hq.gitbook.io/knowledge-base/registration-and-ticketing/ticketing-and-pricing/ticketing-setup)
* [Creating Promo Codes](https://eventx-hq.gitbook.io/knowledge-base/registration-and-ticketing/ticketing-and-pricing/creating-promo-codes)
* [Add-on Item](https://eventx-hq.gitbook.io/knowledge-base/registration-and-ticketing/ticketing-and-pricing/add-on-item)
* [Registration Form Setup](https://eventx-hq.gitbook.io/knowledge-base/registration-and-ticketing/registration-form)

## Frequently Asked Questions

### Q: How are pricing rules different from promo codes?

**A:** Pricing rules override the order total with a fixed price when conditions are met. Promo codes apply a discount (flat amount or percentage) to the existing price. Rules apply after promo codes and first-match-wins.

### Q: Can multiple pricing rules apply to one order?

**A:** No. Only one pricing rule applies per order — the first one whose conditions are satisfied, evaluated top-to-bottom.
