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 Type | Description | Properties |
---|---|---|
stop | Prevent 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” |
confirm | Ask 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_fields | Ask 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_field | Set 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_item | Add 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_item | Remove a line item from the sale | line_item_id : The ID of the line item that you want to remove. |
suggest_products | Suggest 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_customer | Set 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:
Key | Description |
---|---|
event_type | The type of event. In this case: sale.ready_for_payment |
retailer | The retailer the event happened on. |
user | The cashier who triggered the event. |
sale | The sale that is transitioning to the payment screen. |
customer | The customer associated with the sale. |
Allowed actions
The sale.ready_for_payment
event supports these actions:
Action | Description |
---|---|
stop | Don't transition to the payment screen. |
confirm | Ask the cashier for confirmation that we should procceed to the payment screen. |
require_custom_fields | Ask the cashier for values of custom fields. |
set_custom_field | Set a custom field. |
add_line_item | Add a line item. |
remove_line_item | Remove a line item. |
suggest_products | Suggest products to the customer. |
set_customer | Set 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:
Key | Description |
---|---|
event_type | The type of event. In this case: sale.line_items.added |
retailer | The retailer the event happened on. |
user | The cashier who triggered the event. |
sale | The sale that is had the line items added. |
customer | The customer associated with the sale. |
line_items | The 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:
Action | Description |
---|---|
require_custom_fields | Ask the cashier for values of custom fields. |
set_custom_field | Set a custom field. |
add_line_item | Add a line item. |
remove_line_item | Remove a line item. |
suggest_products | Suggest products to the customer. |
set_customer | Set 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:
Key | Description |
---|---|
event_type | The type of event. In this case: sale.line_items.updated |
retailer | The retailer the event happened on. |
user | The cashier who triggered the event. |
sale | The sale that is had the line items updated. |
customer | The customer associated with the sale. |
line_items | The 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:
Action | Description |
---|---|
require_custom_fields | Ask the cashier for values of custom fields. |
set_custom_field | Set a custom field. |
add_line_item | Add a line item. |
remove_line_item | Remove a line item. |
suggest_products | Suggest products to the customer. |
set_customer | Set 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:
Key | Description |
---|---|
event_type | The type of event. In this case: sale.line_items.updated |
retailer | The retailer the event happened on. |
user | The cashier who triggered the event. |
sale | The sale that is had the line items deleted. |
customer | The customer associated with the sale. |
removed_line_items | The 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:
Action | Description |
---|---|
require_custom_fields | Ask the cashier for values of custom fields. |
set_custom_field | Set a custom field. |
add_line_item | Add a line item. |
remove_line_item | Remove a line item. |
suggest_products | Suggest products to the customer. |
set_customer | Set 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:
Key | Description |
---|---|
event_type | The type of event. In this case: sale.customer.changed |
retailer | The retailer the event happened on. |
user | The cashier who triggered the event. |
sale | The sale that is transitioning to the payment screen. |
customer | The customer associated with the sale. |
Allowed actions
The sale.customer.changed
event supports these actions:
Action | Description |
---|---|
require_custom_fields | Ask the cashier for values of custom fields. |
set_custom_field | Set a custom field. |
add_line_item | Add a line item. |
remove_line_item | Remove a line item. |
suggest_products | Suggest products to the customer. |
NOTE: Actions
add_line_item
,remove_line_item
, andsuggest_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:
Key | Description |
---|---|
event_type | The type of event. In this case: sale.created |
retailer | The retailer the event happened on. |
user | The cashier who triggered the event. |
sale | The sale that is transitioning to the payment screen. |
customer | The customer associated with the sale. |
Allowed actions
The sale.created
event supports these actions:
Action | Description |
---|---|
set_custom_field | Set 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:
Key | Description |
---|---|
event_type | The type of event. In this case: sale.updated |
retailer | The retailer the event happened on. |
user | The cashier who triggered the event. |
sale | The sale that is transitioning to the payment screen. |
customer | The customer associated with the sale. |
Allowed actions
The sale.updated
event supports these actions:
Action | Description |
---|---|
set_custom_field | Set a custom field. |
Updated about 1 month ago