Subscriptions V3
The Subscriptions V3 API provides enhanced webhook notifications with expanded event types.
Overview
V3 introduces new webhook events for order voids, refunds, and stock status updates. All webhooks use HMAC-SHA256 authentication for security.
Available Events
The API provides 10 webhook subscription types:
- Order Status Change Request - General status modification requests
- Order Confirmation Request - Merchant confirms order
- Order Rejection Request - Merchant rejects order
- Order Void Request - Order voiding (NEW in V3)
- Order Fulfillment Request - Order fulfillment completion
- Order Refund Request - Full refund processing (NEW in V3)
- Partial Order Refund Request - Partial refund with line-item details (NEW in V3)
- Ready for Pickup Request - Marks order ready for pickup
- Out for Delivery Request - Marks order out for delivery
- Menu Stock Status Update - Stock availability changes (NEW in V3)
Webhook Payloads
All events follow a consistent structure with event metadata and payload data.
Order Status Change Request
This event is triggered when a merchant submits a request to change the status of the order on the POS side. After this action, Order is locked (action is pending) in the POS, until an Order with the changed status is pushed back to it.
Payload Parameters:
| Name | Type | Description |
|---|---|---|
status | string (required) | New status which is requesting to change by POS. |
locationId | integer (required) | The Lighthouse location ID. |
orderId | string (required) | The order identifier which was generated during Order creation. |
waitTimeInMinutes | integer | Required only if status CONFIRMED. This represents the remaining wait time in minutes. If this is a delivery order, it is the estimated number of minutes until delivery to the diner. |
callNumber | string | Available only when the status is CONFIRMED. The call number that has been assigned to the order. |
reasons | array | Required only if status REJECTED. Array of rejection reasons for rejecting the order. At least one reason is provided. |
Response: Successful response 2xx is expected.
In case of a conflicting status, response 409 is expected with a conflict reason:
{
"message": null,
"status": "REJECTED",
"reason": {
"code": "ORDER_CONFIRMATION_WINDOW_EXPIRED",
"explanation": "The Confirmation Window has been expired"
}
}
Event Example:
{
"event": {
"name": "online-ordering.OrderStatusChangeRequest.created",
"component": "online-ordering",
"resource": "OrderStatusChangeRequest",
"action": "created",
"version": "v3",
"subscriptionId": 1,
"dispatchedAt": "2019-04-05T09:26:00.388Z"
},
"payload": {
"status": "CONFIRMED",
"locationId": "{{locationId}}",
"orderId": "{{orderId}}",
"waitTimeInMinutes": 100
}
}
Request to Confirm Order
This event is triggered when a merchant submitted an confirmation action in POS side.
3rd-party is responsible to process a confirmation on their side by changing and pushing back an updated Order.
In general confirmation the process is affecting those Order attributes:
| Name | Type | Description |
|---|---|---|
status | string (required) | Change status to: CONFIRMED |
statusHistory | integer (required) | Add an order confirmation status at statusHistory. The status source should be APP. |
estimatedAt | string | Re-calculate an order estimation depending on waitTimeInMinutes when the food will be ready for pickup or delivered to the diner. |
Request to Reject Order
This event is triggered when a merchant submits a rejection action on the POS side.
Event Example:
{
"event": {
"name": "online-ordering.OrderStatusChangeRequest.created",
"component": "online-ordering",
"resource": "OrderStatusChangeRequest",
"action": "created",
"version": "v3",
"subscriptionId": 1,
"dispatchedAt": "2019-04-05T09:26:00.388Z"
},
"payload": {
"status": "REJECTED",
"locationId": "{{locationId}}",
"orderId": "{{orderId}}",
"reasons": [
{
"code": "STORE_CLOSED",
"explanation": "Restaurant is offline"
}
]
}
}
In general, the process of rejection is affecting the following attributes of an Order:
| Name | Type | Description |
|---|---|---|
status | string (required) | Change status to: REJECTED |
statusHistory | integer (required) | Add an order confirmation status at statusHistory. The status source should be APP. |
Rejection Reason Structure
| Name | Type | Description |
|---|---|---|
code | string (required) | Rejection reason code. Supported rejection reason codes |
explanation | string (required) | Rejection reason explanation |
refs | array | Required only for "resource" specific reason codes, etc, "MISSING_ITEMS" |
Request to Void Order Created (NEW in V3)
This event is triggered when a merchant voids the order on the POS.
{
"event": {
"name": "online-ordering.OrderVoidRequest.created",
"component": "online-ordering",
"resource": "OrderVoidRequest",
"action": "created",
"version": "v3",
"subscriptionId": 1,
"dispatchedAt": "2023-04-05T09:26:00.388Z"
},
"payload": {
"status": "VOIDED",
"locationId": "{{locationId}}",
"orderId": "{{orderId}}"
}
}
In general, the process of voiding is affecting the following attributes of an Order:
| Name | Type | Description |
|---|---|---|
status | string (required) | Change status to: VOIDED |
statusHistory | integer (required) | Add an order confirmation status at statusHistory. The status source should be APP. |
Response: successful response 2xx is expected, otherwise the status would not be changed in POS.
Request to Refund Order Created (NEW in V3)
This event is triggered when an order is refunded on the POS.
{
"event": {
"name": "online-ordering.OrderRefundRequest.created",
"component": "online-ordering",
"resource": "OrderRefundRequest",
"action": "created",
"version": "v3",
"subscriptionId": 1,
"dispatchedAt": "2019-04-05T09:26:00.388Z"
},
"payload": {
"status": "REFUNDED",
"locationId": "{{locationId}}",
"orderId": "{{orderId}}"
}
}
In general, the process of refunding is affecting the following attributes of an Order:
| Name | Type | Description |
|---|---|---|
status | string (required) | Change status to: REFUNDED |
statusHistory | integer (required) | Add an order confirmation status at statusHistory. The status source should be APP. |
Response: successful response 2xx is expected, otherwise the status would not be changed in POS.
Request to Partial Order Refund Created (NEW in V3)
This event is triggered when an order is partially refunded on the POS.
{
"event": {
"name": "online-ordering.OrderPartialRefundRequest.created",
"component": "online-ordering",
"resource": "OrderPartialRefundRequest",
"action": "created",
"version": "v3",
"subscriptionId": 1,
"dispatchedAt": "2019-04-05T09:26:00.388Z"
},
"payload": {
"id": "{{requestId}}",
"appKey": "{{applicationKey}}",
"appRef": "{{orderId}}",
"lineItems": [
{
"posId": "{{lineItemId}}",
"total": 270,
"quantity": 1,
"lineModifiers": [
{
"posId": "{{modifierId}}",
"quantity": 1,
"total": 50,
"lineModifiers": [
{
"posId": "{{nestedModifierId}}",
"quantity": 1,
"total": 20
}
]
}
]
}
],
"surchargeTotal": 0,
"taxTotal": 25,
"tipTotal": 0,
"grandTotal": 295
}
}
Response: successful response 2xx is expected, otherwise the refund would not be processed in POS.
Menu Stock Status Update (NEW in V3)
This event is triggered when a merchant has updated the stock status of a menu item.
{
"event": {
"name": "online-ordering.MenuStockStatus.updated",
"component": "online-ordering",
"resource": "MenuStockStatus",
"action": "updated",
"version": "v3",
"subscriptionId": 1,
"dispatchedAt": "2019-04-05T09:26:00.388Z"
},
"payload": {
"locationId": "{{locationId}}"
}
}
Supported Rejection Reason Codes
V3 supports 19 standardized rejection codes:
| Code | Examples |
|---|---|
POS_NOT_SETUP | POS/AGENT configuration issue |
POS_NOT_READY | Sale ring up in progress, Drawer/Till open, End of Day batchout in progress |
POS_OFFLINE | POS Offline, Internet Outage, Technical issue in-store |
STORE_CLOSED | Store closed, Orders submitted outside of operational hours, Holiday Hours not honored |
STORE_CAPACITY | No open capacity slots, Invalid pickup times, Rejected due to busy store |
ORDER_INFO_MISSING | Missing required Order detail |
ORDER_ADDRESS_INVALID | Missing required address, Invalid geo-coordinates and/or textual identifier |
ORDER_SPECIAL_INSTRUCTIONS | Allergen info provided on order, Utensil opt-in / opt-out instruction |
ORDER_TOTALS_MISMATCH | Mismatch in expected subtotal, Incorrect Tender format |
ITEMS_OUT_OF_STOCK | Order contains out of stock items, Invalid items references expected |
ITEMS_NOT_AVAILABLE | Item not available during service hours (Breakfast, Lunch, Late Night, etc.) |
ITEMS_INFO_MISSING | Item is missing a required choice selection, Invalid quantity rules set in the menu on parent modifier group |
ITEMS_PRICING_MISMATCH | Mismatch in item pricing |
ITEMS_SPECIAL_INSTRUCTIONS | Item level instructions on order |
MODIFIERS_OUT_OF_STOCK | Order contains out of stock items |
MODIFIERS_NOT_AVAILABLE | Item not available during service hours (Breakfast, Lunch, Late Night, etc.) |
MODIFIERS_PRICING_MISMATCH | Mismatch in item pricing |
ORDER_CONFIRMATION_WINDOW_EXPIRED | The POS requested to confirm the order after its confirmation window has been expired on the 3rd-party side |
OTHER | Generic Error Response, Blank/Null Response |
Response Handling
Success Response
Webhooks expect a successful 2xx response for standard processing.
Conflict Response (Status Transitions)
For conflicts (e.g., attempting to confirm an expired order), return 409 status with:
{
"message": null,
"status": "REJECTED",
"reason": {
"code": "ORDER_CONFIRMATION_WINDOW_EXPIRED",
"explanation": "The Confirmation Window has been expired"
}
}
Error Response
For processing failures, return appropriate 4xx or 5xx status codes with descriptive error messages.
Differences from V2
New Event Types
- Order Void Request - Handle order voiding
- Order Refund Request - Full refunds
- Partial Order Refund Request - Line-item refunds
- Menu Stock Status Update - Real-time inventory updates
Order ID Field
- V3 uses
orderIdin payload - V2 used
appRefonly
Enhanced Rejection Codes
- Added
ORDER_CONFIRMATION_WINDOW_EXPIRED - Added
POS_NOT_READYfor specific operational states
Conflict Handling
- V3 explicitly defines 409 response pattern
- Better structured reason objects
Event Naming
- V3:
OrderStatusChangeRequest - V2:
OrderConfirmRequest,OrderRejectRequest(separate events)
Implementation Requirements
Authentication: Implement HMAC-SHA256 signature verification
Response Time: Respond quickly to prevent timeouts
Idempotency: Handle duplicate webhook deliveries gracefully
Error Handling:
- Return 2xx for successful processing
- Return 409 with reason for conflicts
- Return 4xx/5xx for errors
- Implement retry logic for transient failures
Status Synchronization:
- Immediately update local order status
- Add status history entries
- Recalculate estimated times for confirmations
- Propagate changes to customer-facing interfaces