How to React to Lightspeed Retail (X-Series) Events
How to react to Lightspeed Retail (X-Series) Events
In the Lightspeed Retail (X-Series) system it is possible to set up webhooks. These allow events to be generated and sent to a particular given end point when something happens, for example, inventory is updated. You can then handle these events in the system that is catching them and do whatever is appropriate.
What you'll need
Please install Postman, or alternatively, use your favourite software development environment.
With simplicity in mind, we will use a GUI to connect to Lightspeed Retail (X-Series)'s API for this tutorial. Please feel free to use a software development platform instead, but this tutorial will use a GUI tool called Postman.
You should also know how to connect to Lightspeed Retail (X-Series)'s API. See the Quick Start tutorial.
Overview
- Creating Webhooks
- Key concerns
- Testing Webhooks
- Understanding the Payload
- Mapping entities
- Why versions
- Documentation
- Keeping it up to date
- What Next?
Creating Webhooks
The primary way of creating webhooks for OAuth authorized apps is via the /api/webhook endpoint as described here.
Webhooks can also be added “manually” through the hidden API setup page in the Lightspeed Retail (X-Series) backend. This page can be accessed by adding /setup/api
at the end of the store’s URL, i.e. https://<<domain_prefix>>.retail.lightspeed.app/setup/api
.
More details about which webhooks are available and the payloads they return can be found here.
Key Concerns
When receiving entities from the Lightspeed Retail (X-Series) webhook system, it is important to understand the structure of the payload that is returned from the Lightspeed Retail (X-Series) system so that you can successfully map it to whatever you are trying to acccomplish, for example, updating an external system. The Lightspeed Retail (X-Series) system tends to use UUIDs for ids, so you will need to think about how you are going to map this to what you are trying to accomplish. Hopefully, you can use the UUID, but in some cases that will not be possible and so an alternate approach has to be found. We would highly recommend you document these decisions clearly so that both your team mates and your future self will know what you have done and why.
Testing Webhooks
The easiest way to test webhooks is to use one of the free online tools that listen for API requests, but again, use whatever you are most comfortable using. In these examples we will use RequestBin.
Once you have logged into RequestBin you will be given a URL that can be used as the URL for the webhook.
Now that we have the URL we can create a webhook. Enter the hidden URL https://<<domain_prefix>>.retail.lightspeed.app/setup/api
and you should see a page that looks like this:
You can now click on the Add Webhook
and add a webhook.
Adding a Product
If we navigate now to Products https://<<domain_prefix>>.retail.lightspeed.app/products/
we can now add a new product. In this case we will just add a minimal amount of information:
- Name:
A Test Product 001
- Brand:
Generic Brand
- Product Type:
General
- Supplier:
Supplier 1
- Supplier Code:
SUPP-1
- Supply Price: $2.75
Once you click Save
the product will be saved and should appear in the Products list (may require a refresh). In your RequestBin you will see an entry for each outlet, and possibly more, depending on what information you have provided.
The payloads will look similar to this:
{
"root": {
"domain_prefix": "weggieincl",
"environment": "dev",
"payload": {
"attributed_cost": "2.75",
"count": 0,
"id": "d5ea9f64-40c3-8e43-b314-a5aaf7e80e73",
"outlet": {
"id": "0242ac12-0002-11e9-e8c4-659494e196e3",
"name": "Massey (Sale)",
"tax_id": "00000000-0002-0002-0002-000000000003",
"time_zone": "Pacific/Auckland"
},
"outlet_id": "0242ac12-0002-11e9-e8c4-659494e196e3",
"product": {
"active": true,
"attributed_cost": null,
"base_name": "A Test Product 001",
"button_order": null,
"categories": [],
"deleted_at": null,
"description": "",
"handle": "atestproduct001",
"id": "ad85c7cc-cc13-ba7f-ce8a-3602b8fe3d12",
"name": "A Test Product 001",
"sku": "10013",
"source": "USER",
"source_id": null,
"source_variant_id": null,
"supply_price": "2.75",
"taxes": [
{
"outlet_id": "0242ac12-0002-11e9-e8c4-659494dde2eb",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-659494e196e3",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-6594953122f6",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-6594953eb634",
"tax_id": "00000000-0002-0002-0002-000000000003"
}
],
"variant_options": [],
"variant_parent_id": null
},
"product_id": "ad85c7cc-cc13-ba7f-ce8a-3602b8fe3d12",
"reorder_point": "0",
"restock_level": "0",
"version": 1165
},
"retailer_id": "00000000-0001-0001-0001-000000000001",
"type": "inventory.update"
}
}
The only difference between the payloads will be the outlet
, outlet_id
and version
information in this case.
Understanding the Payload
An initial scan of these payloads may have you wondering what you are going to do with all those ids that are listed. However, a closer look will show that nearly all the ids are expanded to include the details of what the id points to. In this payload we have ids for outlet and product, but we also have details for both the outlet and product referenced by those ids. The only id that is not expanded in this case is the tax id (as this only referenced in the expanded outlet section). If you need the details for the tax id you would need to make a call to https://<<domain_prefix>>.retail.lightspeed.app/api/taxes/02dcd191-ae2b-11e9-f336-cd2e6d864598
.
Editing a Product
If you now edit the product you created above and add some stock for Massey and Newmarket you should get new payloads for those two stores with update counts.
{
"root": {
"domain_prefix": "weggieincl",
"environment": "dev",
"payload": {
"attributed_cost": "2.75",
"count": 5,
"id": "d5ea9f64-40c3-8e43-b314-a5aaf7e80e73",
"outlet": {
"id": "0242ac12-0002-11e9-e8c4-659494e196e3",
"name": "Massey (Sale)",
"tax_id": "00000000-0002-0002-0002-000000000003",
"time_zone": "Pacific/Auckland"
},
"outlet_id": "0242ac12-0002-11e9-e8c4-659494e196e3",
"product": {
"active": true,
"attributed_cost": null,
"base_name": "A Test Product 001",
"button_order": null,
"categories": [],
"deleted_at": null,
"description": "",
"handle": "atestproduct001",
"id": "ad85c7cc-cc13-ba7f-ce8a-3602b8fe3d12",
"name": "A Test Product 001",
"sku": "10013",
"source": "USER",
"source_id": null,
"source_variant_id": null,
"supply_price": "2.75",
"taxes": [
{
"outlet_id": "0242ac12-0002-11e9-e8c4-659494dde2eb",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-659494e196e3",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-6594953122f6",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-6594953eb634",
"tax_id": "00000000-0002-0002-0002-000000000003"
}
],
"variant_options": [],
"variant_parent_id": null
},
"product_id": "ad85c7cc-cc13-ba7f-ce8a-3602b8fe3d12",
"reorder_point": "0",
"restock_level": "0",
"version": 1173
},
"retailer_id": "00000000-0001-0001-0001-000000000001",
"type": "inventory.update"
}
}
{
"root": {
"domain_prefix": "weggieincl",
"environment": "dev",
"payload": {
"attributed_cost": "2.75",
"count": 11,
"id": "00aec235-dd25-5280-9c41-75678683a9c6",
"outlet": {
"id": "0242ac12-0002-11e9-e8c4-659494dde2eb",
"name": "Newmarket (Base)",
"tax_id": "00000000-0002-0002-0002-000000000003",
"time_zone": "Pacific/Auckland"
},
"outlet_id": "0242ac12-0002-11e9-e8c4-659494dde2eb",
"product": {
"active": true,
"attributed_cost": null,
"base_name": "A Test Product 001",
"button_order": null,
"categories": [],
"deleted_at": null,
"description": "",
"handle": "atestproduct001",
"id": "ad85c7cc-cc13-ba7f-ce8a-3602b8fe3d12",
"name": "A Test Product 001",
"sku": "10013",
"source": "USER",
"source_id": null,
"source_variant_id": null,
"supply_price": "2.75",
"taxes": [
{
"outlet_id": "0242ac12-0002-11e9-e8c4-659494dde2eb",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-659494e196e3",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-6594953122f6",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-6594953eb634",
"tax_id": "00000000-0002-0002-0002-000000000003"
}
],
"variant_options": [],
"variant_parent_id": null
},
"product_id": "ad85c7cc-cc13-ba7f-ce8a-3602b8fe3d12",
"reorder_point": "0",
"restock_level": "0",
"version": 1174
},
"retailer_id": "00000000-0001-0001-0001-000000000001",
"type": "inventory.update"
}
}
Deleting a Product
When a product is deleted in Lightspeed Retail (X-Series), you will get a webhook sent with the UTC datetime deleted_at
specified.
{
"root": {
"domain_prefix": "weggieincl",
"environment": "dev",
"payload": {
"attributed_cost": "5.50",
"count": 21,
"id": "f6141e12-c435-dae2-53e2-d6e06876c61d",
"outlet": {
"id": "0242ac12-0002-11e9-e8c4-659494dde2eb",
"name": "Newmarket (Base)",
"tax_id": "00000000-0002-0002-0002-000000000003",
"time_zone": "Pacific/Auckland"
},
"outlet_id": "0242ac12-0002-11e9-e8c4-659494dde2eb",
"product": {
"active": false,
"attributed_cost": null,
"base_name": "A Test Product 002",
"button_order": null,
"categories": [],
"deleted_at": "2022-05-13T20:34:46Z",
"description": "",
"handle": "atestproduct002",
"id": "08d107a2-0c70-683e-9eb7-58a1bfb27b13",
"name": "A Test Product 002",
"sku": "10014",
"source": "USER",
"source_id": null,
"source_variant_id": null,
"supply_price": "5.50",
"taxes": [
{
"outlet_id": "0242ac12-0002-11e9-e8c4-659494dde2eb",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-659494e196e3",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-6594953122f6",
"tax_id": "00000000-0002-0002-0002-000000000003"
},
{
"outlet_id": "0242ac12-0002-11e9-e8c4-6594953eb634",
"tax_id": "00000000-0002-0002-0002-000000000003"
}
],
"variant_options": [],
"variant_parent_id": null
},
"product_id": "08d107a2-0c70-683e-9eb7-58a1bfb27b13",
"reorder_point": "0",
"restock_level": "0",
"version": 1201
},
"retailer_id": "00000000-0001-0001-0001-000000000001",
"type": "inventory.update"
}
}
Updating and Deleting Webhooks
You can update webhooks with the PUT
https://<<domain_prefix>>.retail.lightspeed.app/api/webhooks/:webhook_id
endpoint and delete a webhook using the DELETE
https://<<domain_prefix>>.retail.lightspeed.app/api/webhooks/:webhook_id
endpoint.
Updated 9 months ago