Business Rules

Business Rules

Business Rules are customizable rules that get executed at different lifecycle events on a sale in Lightspeed Retail (X-Series). The logic in your business rules runs on your own server, and Lightspeed Retail (X-Series) will call out to your server to execute the rules. We call these Remote Rules since the logic does not exist within Lightspeed Retail (X-Series).

To get started you need to register your Remote Rule endpoint in Lightspeed Retail (X-Series) via our API and create a Rule to trigger the Remote Rule.

This feature is only available on Enterprise plans.

Creating a Remote Business Rule

To create a Remote Rule you simply register the endpoint of your Remote Rule with Lightspeed Retail (X-Series):

POST /api/2.0/workflows/remote_rules

In the payload you specify the URL of the Remote Rule on your server:

{
  "url": "https://mycompany.com/vend-business-rule"
}

As a response, you will get a RemoteRule object:

{
  "data": {
    "id": "238757382938758342",
    "url": "https://mycompany.com/vend-busniess-rule",
    "created_at": "2022-02-28T14:22:13Z"
  }
}

For more details see the Create Remote Rule documentation

Creating a Rule

While the Remote Rule is used to register your business rule endpoint in Lightspeed Retail (X-Series), a Rule is used to associate the Remote Rule with a specific lifecycle event in Lightspeed Retail (X-Series).

To create a Rule to trigger your Remote Rule simply create a Rule in Lightspeed Retail (X-Series):

POST /api/2.0/workflows/rules

In the payload to specify the event that should trigger the Remote Rule and the ID of the Remote Rule:

{
  "event_type": "sale.ready_for_payment",
  "remote_rule_id": "238757382938758342"
}

As a response, you will get a Rule object:

{
  "data": {
    "id": "938484920947573",
    "event_type": "sale.ready_for_payment",
    "remote_rule_id": "238757382938758342",
    "created_at": "2022-02-28T14:23:26Z"
  }
}

For more details see the Create Rule documentation

Remote Business Rule API

Now that you have registered your Remote Rule in Lightspeed Retail (X-Series) and created a Rule to trigger it, Lightspeed Retail (X-Series) will call your end-point every time the sale.ready_for_payment event occurs.

A Remote Rule is called via an HTTP JSON POST request at the URL registered.

The Remote Rule is sent information about the event that is happening and can respond with a list of actions to instruct Lightspeed Retail (X-Series) how to proceed.

The payload for an event always has the event_type and retailer. Depending on the event type, the payload will have additional fields describing the context of the event.

As a response to the request, the Remote Rule must return a list of actions for Lightspeed Retail (X-Series) to perform.

Timeout

There is a 2 second window for a response from the event triggering the rule. If a response is not received with valid actions within 2 seconds, a timeout will occur.

Actions

Action TypeDescriptionProperties
stopPrevent the event from continuing.title: The title of the modal.
Default: ””

message: The message of the modal.

dismiss_label: The label of the OK button on the modal.
Default: ”OK”
confirmAsk the user to confirm that they want to proceed.title: The title of the modal.
Default: ””

message: The message of the modal.

confirm_label: The label on the button to proceed with the event.
Default: "Continue"

dismiss_label: The label on the button to not proceed with the event.
Default: "Cancel"
require_custom_fieldsAsk the user to enter values for custom fields.title: The title of the modal.
Default: ””

message: The message of the modal.

entity: The type of entity you want to set a custom field on. Must be either sale or line_item.

entity_id: The ID of the entity that you want to set the custom field on. This is only required when setting a custom field on a line item.

required_custom_fields: The custom fields that are required.
set_custom_fieldSet value for a custom field.entity: The type of entity you want to set a custom field on. Must be either sale or line_item.

entity_id: The ID of the entity that you want to set the custom field on. This is only required when setting a custom field on a line item.

custom_field_name: The name of the custom field that you are setting value of.

custom_field_value: The value that you want to set on the custom field.
add_line_itemAdd a line item to the sale.product_id: The ID of the product that you want to add.

product_sku: The SKU of the product that you want to add.

quantity: The quantity of the product that you want to add.
Default: "1"

unit_price: Use this to override the price of 1 unit of the product.
Default: The default unit price of the product.

note: A note you want to add on the line item.

Note: You must specify either the product_id or product_sku, not both.
remove_line_itemRemove a line item from the saleline_item_id: The ID of the line item that you want to remove.
suggest_productsSuggest a list of products to the customer.title: The title of the modal.
Default: ”Suggested Products”

message: The message of the modal.
Default: ”Please suggest these products to the customer:”

suggested_products: The products that you want to suggest to the customer.
set_customerSet or unset the customer on a sale.customer_id: The ID of the customer you want to set or null if you want to unset the customer.

The stop Action

An example response payload with a stop action looks like this:

{
  "actions": [
    {
      "type": "stop",
      "title": "No sale of alcohol to minors",
      "message": "The customer must be at least 21 years old to buy alcohol.",
      "dismiss_label": "OK"
    }
  ]
}

This action would produce a popup on the screen like this:

The confirm Action

An example response payload with a confirm action looks like this:

{
  "actions": [
    {
      "type": "confirm",
      "title": "✋ ID Check",
      "message": "Please confirm than you have checked to ID of the customer.",
      "confirm_label": "Done",
      "dismiss_label": "Cancel"
    }
  ]
}

This action would produce a popup on the screen like this:

The require_custom_fields Action

An example response payload with a require_custom_fields action looks like this:

{
  "actions": [
    {
      "type": "require_custom_fields",
      "title": "We need some information about this return",
      "message": "Please explain why this item is being returned",
      "entity": "line_item",
      "entity_id": "cc0e2f8f-3c14-ac66-11ea-9e2e4fefb804",
      "required_custom_fields": [
        {
          "name": "return-reason",
          "values": [
            {
              "value": "broken",
              "title": "The item is broken"
            },
            {
              "value": "wrong-size",
              "title": "The item does not fit"
            },
            {
              "value": "other",
              "title": "Other (Please describe below)"
            }
          ]
        },
        {
          "name": "return-note"
        }
      ]
    }
  ]
}

This action would produce a popup on the screen like this:

The set_custom_field Action

An example response payload with a set_custom_field action looks like this:

{
  "actions": [
    {
      "type": "set_custom_field",
      "entity": "sale",
      "custom_field_name": "contains-alcohol",
      "custom_field_value": true
    }
  ]
}

The add_line_item Action

An example response payload with a add_line_item action that adds a product by ID, looks like this:

{
  "actions": [
    {
      "type": "add_line_item",
      "product_id": "0242ac12-0002-11e9-e8c4-659494e33153"
    }
  ]
}

Alternatively, you can add a product by SKU:

{
  "actions": [
    {
      "type": "add_line_item",
      "product_sku": "bottle-deposit"
    }
  ]
}

You can optionally set the quantity, unit price, and note as well:

{
  "actions": [
    {
      "type": "add_line_item",
      "product_id": "0242ac12-0002-11e9-e8c4-659494e33153",
      "quantity": "2.4",
      "unit_price": "3.75",
      "note": "Such an awesome line item!"
    }
  ]
}

The remove_line_item Action

An example response payload with a remove_line_item action looks like this:

{
  "actions": [
    {
      "type": "remove_line_item",
      "line_item_id": "0242ac12-0002-11e9-e8c4-659494e33153"
    }
  ]
}

The suggest_products Action

An example response payload with a suggest_products action looks like this:

{
  "actions": [
    {
      "type": "suggest_products",
      "title": "Suggested Products",
      "message": "Please suggest these products to the customer:",
      "suggested_products": [
        {
          "product_sku": "sunglasses"
        },
        {
          "product_id": "0242ac12-0002-11e9-f1df-d3978176d123"
        }
      ]
    }
  ]
}

This action would produce a popup on the screen like this:

The set_customer Action

An example response payload with a set_customer action looks like this:

{
  "actions": [
    {
      "type": "set_customer",
      "customer_id": "0242ac12-0002-11e9-e8c4-659494e33153"
    }
  ]
}

Event types

Different events are triggered by Lightspeed Retail (X-Series) during the lifecycle of a sale.
Currently, we support the following events:

sale.ready_for_payment

The sale.ready_for_payment is triggered by the register when transitioning to the payment screen.

Payload

The payload sent to you when this event occours, has the folowing contents:

KeyDescription
event_typeThe type of event. In this case: sale.ready_for_payment
retailerThe retailer the event happened on.
userThe cashier who triggered the event.
saleThe sale that is transitioning to the payment screen.
customerThe customer associated with the sale.

Allowed actions

The sale.ready_for_payment event supports these actions:

ActionDescription
stopDon't transition to the payment screen.
confirmAsk the cashier for confirmation that we should procceed to the payment screen.
require_custom_fieldsAsk the cashier for values of custom fields.
set_custom_fieldSet a custom field.
add_line_itemAdd a line item.
remove_line_itemRemove a line item.
suggest_productsSuggest products to the customer.
set_customerSet or unset the customer on the sale.

sale.line_items.added

The sale.line_items.added is triggered by the register when line items are added to a sale.

Payload

The payload sent to you when this event occours has the folowing contents:

KeyDescription
event_typeThe type of event. In this case: sale.line_items.added
retailerThe retailer the event happened on.
userThe cashier who triggered the event.
saleThe sale that is had the line items added.
customerThe customer associated with the sale.
line_itemsThe line items that were added.

An example request payload for a sale.line_items.added event looks like this:

{
  "event_type": "sale.line_items.added",
  "retailer": {
    "id": "b1ed6158-f019-11e3-a0f5-b8ca3a64f8f4",
    "domain_prefix": "company"
  },
  "user": {
    "id": "08002782-0c90-11e6-e3ed-117ec127b1ca",
    "username": "Admin",
    "email": null,
    "account_type": "admin"
  },
  "sale": {
    "id": "1232ac12-0002-11e9-e8c4-659494dde2eb",
    "status": "SAVED",
    "return_for": "6782ac12-0002-11e9-e8c4-659494dde2eb",
    "outlet_id": "0242ac12-0002-11e9-e8c4-659494dde2eb",
    "register_id": "0242ac12-0002-11e9-e8c4-659494ddca3d",
    "note": "Sale Note",
    "total_price": "69.56521739130434",
    "total_tax": "10.43478260869565",
    "custom_fields": [
      {
        "definition_id": "1247745546911297536",
        "name": "age_verified",
        "boolean_value": true
      }
    ],
    "line_items": [
      {
        "id": "cc0e2f8f-3c14-974a-11ea-67fafc89e3ff",
        "product": {
          "id": "0242ac12-0002-11e9-e8c4-659494e33153",
          "custom_fields": [
            {
              "definition_id":"1249847800380837242",
              "name": "requires_age_verification",
              "boolean_value": true
            }
          ]
        },
        "quantity": "1",
        "note": "Line Item Note",
        "price": "34.78260869565217",
        "price_total": "34.78260869565217",
        "tax_total": "5.217391304347825",
        "custom_fields": [
          {
            "definition_id":"1249847800380837888",
            "name": "serial",
            "string_value": "SN3847sj-34"
          }
        ]
      },
      {
        "id": "cc0e2f8f-3c14-974a-11ea-6896792dfeae",
        "product": {
          "id": "0242ac11-0002-11ea-f7e1-629be820260d",
          "custom_fields": []
        },
        "quantity": "1",
        "note": "Line Item Note",
        "price": "34.78260869565217",
        "price_total": "34.78260869565217",
        "tax_total": "5.217391304347825",
        "custom_fields": []
      }
    ]
  },
  "customer": {
    "id": "0242ac11-0002-11ea-f7e1-629be9455e72",
    "first_name": "Anthony",
    "last_name": "Stark",
    "customer_code": "Tony-N4ZJ",
    "customer_group_id": "28020918-a068-aae4-11e9-cad0d05570c9",
    "email": "[email protected]",
    "phone": "123 456 7890",
    "mobile": "123 456 7890",
    "fax": "123 456 7890",
    "do_not_email": true,
    "note": "Customer Note",
    "date_of_birth": "1963-03-03",
    "year_to_date": "0",
    "balance": "0",
    "loyalty_balance": "0",
    "created_at": "2020-03-10T06:53:56+00:00",
    "enable_loyalty": false,
    "custom_field_1": "Custom data one",
    "custom_field_2": null,
    "custom_field_3": null,
    "custom_field_4": null
  },
  "line_items": [
    {
      "id": "cc0e2f8f-3c14-974a-11ea-6896792dfeae",
      "product": {
        "id": "0242ac11-0002-11ea-f7e1-629be820260d",
        "custom_fields": []
      },
      "quantity": "1",
      "note": "Line Item Note",
      "price": "34.78260869565217",
      "price_total": "34.78260869565217",
      "tax_total": "5.217391304347825",
      "custom_fields": []
    }
  ]
}

Allowed actions

The sale.line_items.added event supports these actions:

ActionDescription
require_custom_fieldsAsk the cashier for values of custom fields.
set_custom_fieldSet a custom field.
add_line_itemAdd a line item.
remove_line_itemRemove a line item.
suggest_productsSuggest products to the customer.
set_customerSet or unset the customer on the sale.

sale.line_items.updated (Currently not supported on mobile app)

Warning: This is triggered for quantity change, price changed and discount percentage change. As these fields dynamically update you will always get three events from this workflow.

The sale.line_items.updated is triggered by the register when line items are updated in a sale. The fields that trigger this are quantity, cost and discount.

Payload

The payload sent to you when this event occours has the following contents:

KeyDescription
event_typeThe type of event. In this case: sale.line_items.updated
retailerThe retailer the event happened on.
userThe cashier who triggered the event.
saleThe sale that is had the line items updated.
customerThe customer associated with the sale.
line_itemsThe line items that were updated.

Essentially the payload will be identical to that of sale.line_items.added except for the event type.

Allowed actions

The sale.line_items.updated event supports these actions:

ActionDescription
require_custom_fieldsAsk the cashier for values of custom fields.
set_custom_fieldSet a custom field.
add_line_itemAdd a line item.
remove_line_itemRemove a line item.
suggest_productsSuggest products to the customer.
set_customerSet or unset the customer on the sale.

sale.line_items.deleted (Currently not supported on mobile app)

The sale.line_items.deleted is triggered when a line item is deleted from a sale.

Payload

The payload sent to you when this event occurs has the following contents:

KeyDescription
event_typeThe type of event. In this case: sale.line_items.updated
retailerThe retailer the event happened on.
userThe cashier who triggered the event.
saleThe sale that is had the line items deleted.
customerThe customer associated with the sale.
removed_line_itemsThe line item ids that were removed.

An example request payload for a sale.line_items.deleted event is given below. Note the removed_line_item_ids section, which is an array of deleted ids (normally will only be 1).

{
    "event_type": "sale.line_items.deleted",
    "retailer_id": "00000000-0001-0001-0001-000000000001",
    "retailer": {
        "id": "00000000-0001-0001-0001-000000000001",
        "domain_prefix": "company"
    },
    "sale": {
        "id": "0f6799a5-3a64-b647-11ed-a739c219e537",
        "status": "OPEN",
        "outlet_id": "0242ac12-0002-11e9-e8c4-659494e196e4",
        "register_id": "0242ac12-0002-11e9-e8c4-659494e17cef",
        "line_items": [],
        "note": "",
        "total_price": "0",
        "total_tax": "0",
        "custom_fields": []
    },
    "user": {
        "id": "08002782-0c90-11e6-e3ed-117ec127b1cb",
        "username": "Admin",
        "account_type": "admin"
    },
    "removed_line_item_ids": [
        "0f6799a5-3a64-a36a-11ed-a7f857d968aa"
    ]
}

Allowed actions

The sale.line_items.deleted event supports these actions:

ActionDescription
require_custom_fieldsAsk the cashier for values of custom fields.
set_custom_fieldSet a custom field.
add_line_itemAdd a line item.
remove_line_itemRemove a line item.
suggest_productsSuggest products to the customer.
set_customerSet or unset the customer on the sale.

sale.customer.changed

The sale.customer.changed is triggered by the register when a customer is set or unset on a sale.

Payload

The payload sent to you when this event occours, has the folowing contents:

KeyDescription
event_typeThe type of event. In this case: sale.customer.changed
retailerThe retailer the event happened on.
userThe cashier who triggered the event.
saleThe sale that is transitioning to the payment screen.
customerThe customer associated with the sale.

Allowed actions

The sale.customer.changed event supports these actions:

ActionDescription
require_custom_fieldsAsk the cashier for values of custom fields.
set_custom_fieldSet a custom field.
add_line_itemAdd a line item.
remove_line_itemRemove a line item.
suggest_productsSuggest products to the customer.

NOTE: Actions add_line_item, remove_line_item, and suggest_products are ignored if the user has already recorded payment for the sale (i.e. they are on the Complete Sale page).

sale.created

The sale.created is triggered when a sale has been created.

Payload

The payload sent to you when this event occours, has the folowing contents:

KeyDescription
event_typeThe type of event. In this case: sale.created
retailerThe retailer the event happened on.
userThe cashier who triggered the event.
saleThe sale that is transitioning to the payment screen.
customerThe customer associated with the sale.

Allowed actions

The sale.created event supports these actions:

ActionDescription
set_custom_fieldSet a custom field.

sale.updated

The sale.updated is triggered when a sale has been created.

Payload

The payload sent to you when this event occours, has the folowing contents:

KeyDescription
event_typeThe type of event. In this case: sale.updated
retailerThe retailer the event happened on.
userThe cashier who triggered the event.
saleThe sale that is transitioning to the payment screen.
customerThe customer associated with the sale.

Allowed actions

The sale.updated event supports these actions:

ActionDescription
set_custom_fieldSet a custom field.