Order Management
After a merchant connects one of your locations to Stream, they will be able to recieve orders from us into your POS system via the Handle Order (Stream -> POS) endpoint.
As we process an order, there are multiple actions that may take place before the final fulfillment of the order. These actions include:
Unpaid orders are not enabled by default on the POS integration. If you would like to allow unpaid orders, please reach out to Partner API support to enable this for your integration.
Order Fulfillment Types
There are multiple types of fulfillment that can be submitted through Stream.
- delivery: An order that is being delivered to a customer.
- merchant_managed_delivery: An order that is being delivered to a customer by a merchant's employee / dispatch system.
- pickup: An order that is being picked up by a customer.
- curbside: An order that is being picked up by a customer at a curbside location.
- drive_thru: An order that is being picked up at a drive thru window.
Order Validation
When an order insertion is attempted into the POS, you should perform validations that will ensure the order criteria can be met.
Type | Example |
---|---|
Stock Validation | Item/Modifier Inventory Checks |
Order Totals Validation | Order SubTotal Greater Then Or Equal POS Check |
Unknown Validation | Unsupported Errors That Will Fail Without Reason to DSP |
Returning the JSON below along with a 400 status code to the Handle Order (Stream -> POS) endpoint will fail this validation.
{
"posValidation": {
"stockValidation": [
{
"type": "item",
"provider_id": "string",
"quantity": 0
}
],
"orderTotalsValidation": [
{
"posTotal": 0,
"streamTotal": 0
}
],
"unknownValidation": [
{
"order_error": "string",
"order_error_reason": "string"
}
]
}
}
Order Acceptance
Upon a successful 200 response from the Handle Order (Stream -> POS) endpoint with order.created
, we will consider the order accepted and inserted into the POS successfully, from this point we will report to the DSP the order is accepted and can move on in the process. The only details needed to be returned in this 2xx response upon success is the order.provider_id
, which will be used for future communication regarding the order.
Dynamic Prep Time
For dynamic control of preparation time upon order submission, include prep_time_minutes
in your acceptance response.
Future Orders
When platforms opt in to notifying the POS in advance of the order preparation, in this case the order will come in with is_future_order
set to true
and requested_for
set to the estimated fulfillment time.
Uber and Doordash will hold the order on their end and notify us similarly to that of an ASAP order, in this case you will not recieve any indication that it was a future order.
Order Status Updates
When a merchant updates the order status within the POS,Y you can send an event to POS Status Update (POS -> Stream) endpoint with order.status.updated
with the relevant status. The order status inside Stream will be updated instantly but one caveat to mention is the propegation of this status change to DSP is WIP and will be implemented before end of Q4.
Status | Description |
---|---|
ready_for_pickup | This signals the order is prepared and ready to be picked up by the DSP. Usage of this status can decrease the time the food sits on the shelf waiting for a driver. |
completed | This signals the order has been picked up by a driver or a customer and has no further actions. |
merchant_canceled | This signals the order has been cancelled by the store. |
Canceling Orders
Although we do our best to make sure that orders that can not be fulfilled do not get accepted through the validation above, sometimes there are cases when an order will be cancelled post-acceptance by either the Merchant or the DSP. In this case, you will recieve a order.canceled
event to the Handle Order (Stream -> POS) endpoint.
The above information is for DSP / Whitelabel invoked cancellations. Orders can also be marked as canceled from within the POS, using the order.status.updated
and using the order status of merchant_canceled
. Handle Webhook Event (POS -> Stream)
Order Calculation
To understand the amounts provided in the order data, refer to the following information.
Field | Description |
---|---|
Subtotal | Amount of all items in the order prior to tax |
Taxes | Amount of taxes charged to the customer and paid to the merchant |
Taxes Witheld by DSP | Amount of taxes charged to the customer and paid to the DSP |
Order Markup Values
The default behavior for item markups is to submit the order into the POS at the price it was ordered on the DSP, inclusive of markup.
To recieve order markup total as a distinct line item, please reach out to Partner API support to enable this for your integration.
If enabled, it will be provided like the following example where the markup total across all items on the order is $2.50.
"line_items": [
...,
{
"name": "Uber Markup",
"quantity": 1,
"price_amount": 250,
"price_currency": "usd",
"modifiers": []
}
],
Order Discounts
When a promotion is configured on the ordering channel, we will attach this information on the order to allow for accurate reporting within the POS.
This discount information can be in two forms, order level and item level.
When you have an order level discount, the items
will be omitted from the discount record.
"discounts": [
{
"provider_id": "discount_id",
"amount": 250,
}
],
When you have an item level discount, the items will reference the applicable items for the discount.
"discounts": [
{
"provider_id": "discount_id",
"amount": 250,
"items": [
{
"provider_id": "variation_id",
}
]
}
],