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 Plus 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/{version}/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/{version}/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.
The user object
user objectEvents triggered by the register include a user object describing the cashier who triggered the event:
| Key | Description |
|---|---|
id | The ID of the user. |
username | The username of the user. |
email | The email address of the user, or null. |
account_type | The account type of the user: cashier, manager or admin. |
locale | Optional. The language the cashier is currently using on the register, as a BCP 47 language tag, for example fr-CA. Use it to localize the title, message and other text of the actions you return. |
The locale key is only present when the register reports it. Cashiers can change the display language on each register, so it can differ from the retailer's default culture. When locale is missing, fall back to the retailer's culture.
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" |
add_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.custom_fields: The custom fields that are required.skippable: (true/false) The custom field input can be skipped. |
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.tax_id: The ID of the tax to apply to 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. |
set_line_item_tax | Set the tax on a specific line item. | line_item_id: The ID of the line item to set the tax on.tax_id: The ID of the tax to apply to the line item. |
The stop Action
stop ActionAn 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
confirm ActionAn 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 add_custom_fields Action
add_custom_fields ActionAn example response payload with a add_custom_fields action looks like this:
{
"actions": [
{
"type": "add_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",
"skippable": true,
"add_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
set_custom_field ActionAn 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
add_line_item ActionAn 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!"
}
]
}WARNING: Line item consolidation is disabled when this action is performed. This means that the product will be added as a new line item even if the same product exists in the sale.
The remove_line_item Action
remove_line_item ActionAn 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
suggest_products ActionAn 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"
}
]
}The set_line_item_tax Action
set_line_item_tax ActionUse set_line_item_tax to change a line item's tax to the tax identified by tax_id. Both line_item_id and tax_id are required.
An example response payload with a set_line_item_tax action looks like this:
{
"actions": [
{
"type": "set_line_item_tax",
"line_item_id": "0242ac12-0002-11e9-e8c4-659494e33153",
"tax_id": "0242ac12-0002-11e9-e8c4-1a2b3c4d5e6f"
}
]
}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 occurs, has the following 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 proceed to the payment screen. |
add_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. |
set_line_item_tax | Set the tax on a specific line item. |
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 occurs has the following 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 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",
"locale": "fr-CA"
},
"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",
"tax_id": "0242ac12-0002-11e9-e8c4-659494e00001",
"tax_components": [
{
"rate_id": "0242ac12-0002-11e9-e8c4-659494e00002",
"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",
"tax_id": "0242ac12-0002-11e9-e8c4-659494e00001",
"tax_components": [
{
"rate_id": "0242ac12-0002-11e9-e8c4-659494e00002",
"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,
"enable_promotional_sms": 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",
"tax_id": "0242ac12-0002-11e9-e8c4-659494e00001",
"tax_components": [
{
"rate_id": "0242ac12-0002-11e9-e8c4-659494e00002",
"tax_total": "5.217391304347825"
}
],
"custom_fields": []
}
]
}Allowed actions
The sale.line_items.added event supports these actions:
| Action | Description |
|---|---|
add_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. |
set_line_item_tax | Set the tax on a specific line item. |
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 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 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 |
|---|---|
add_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. |
set_line_item_tax | Set the tax on a specific line item. |
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 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 |
|---|---|
add_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. |
set_line_item_tax | Set the tax on a specific line item. |
sale.line_items.split (Currently not supported on mobile app)
The sale.line_items.split is triggered by the register when line items are split in 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.split |
retailer | The retailer the event happened on. |
user | The cashier who triggered the event. |
sale | The sale that had the line items split. |
customer | The customer associated with the sale. |
line_items | The line item that was split. |
Essentially the payload will be identical to that of sale.line_items.added except for the event type.
Allowed actions
The sale.line_items.split event supports these actions:
| Action | Description |
|---|---|
add_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. |
set_line_item_tax | Set the tax on a specific line item. |
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 occurs, has the following 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 |
|---|---|
add_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_line_item_tax | Set the tax on a specific line item. |
NOTE: Actions
add_line_item,remove_line_item, andsuggest_productsare 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 occurs, has the following 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 occurs, has the following 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 22 hours ago
