Order Fulfillment
While you submit orders to Stream, there are multiple methods of fulfillment that can be used based on the needs of the order. These types include:
Order Fulfillment Types
There are multiple types of fulfillment that can be submitted to 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.
- dine_in: An order that is being taken at a dine in location.
Orders default to paid. An order sent without unpaid: true is submitted to the merchant's POS as already paid, even when fulfillment_type is "drive_thru". To have the merchant collect payment at fulfillment you must explicitly set unpaid: true on the order — see Unpaid Orders.
Only orders with a fulfillment_type of "drive_thru" may be submitted as unpaid. "pickup" and "delivery" can be supported on a per-request basis. All other orders submitted through this integration must be paid at the time of submission.
Delivery
- Used for orders that are being delivered to a customer, with all delivery components and details managed by the DSP partner. Treated similar to a pickup order from a POS perspective.
Pickup
- Used for orders that are being picked up by a customer, can leverage the ready_for_pickup status to notify the customer that their order is ready.
Curbside
- Used for orders that are being picked up by a customer at a curbside location, can leverage the ready_for_pickup status to notify the customer that their order is ready but we do not offer a customer -> pos arrival notification.
Drive Thru
Used for orders that are being picked up at a drive thru window.
Supports pay-at-window operations, but the order is only treated as unpaid if you send
unpaid: trueon it.fulfillment_type: "drive_thru"on its own does not change the payment state of the order — see Unpaid Orders.
Merchant Managed Delivery
Used for orders that are being delivered to a customer by a merchant's employee / dispatch system.
Populate the
delivery_addressfield to submit the delivery address details.Populate the
fulfillment_instructionsfield to submit the delivery instructions.Populate the
driver_tipwith relevant tip information for driver.Populate the
delivery_feeand/ordelivery_fee_taxeswith relevant delivery fee information for reconciliation.
Delivery Status Updates
For merchant_managed_delivery orders that are dispatched by a connected dispatch system, Stream sends delivery events to your webhook endpoint at /stream-dsp/v1/event to keep you informed of the delivery progress. These events are sent automatically as the delivery status changes.
Event Structure
Stream sends a delivery_status_update event with the following structure:
{
"type": "delivery_status_update",
"delivery_status": "enroute_to_pickup",
"order_id": "your_order_id",
"location_id": "your_location_id",
"driver_details": {
"source": "doordash",
"name": "John Driver",
"phone": {
"number": "+15555551234",
"code": "123"
},
"vehicle_info": {
"make": "Toyota",
"model": "Camry",
"color": "Silver",
"license_plate": "ABC1234"
},
"handoff_instructions": "Please verify driver ID",
"passcode": "1234"
}
}
Driver Details
When a driver is assigned, the driver_details object is included in the event payload. This contains driver contact information, vehicle details, handoff instructions, and a passcode for merchant verification.
Configuration
No additional configuration is required to receive delivery status updates. These events are automatically sent to your existing webhook endpoint at /stream-dsp/v1/event once an order with fulfillment_type of merchant_managed_delivery is accepted.
Dine In
Used for orders that are placed for a customer dining in at the location.
Populate the optional
table_numberfield with the customer's table number. When provided, it is placed on the POS ticket so staff can deliver the order to the correct table.
Unpaid Orders
An unpaid order is one where your platform has not collected payment and the merchant collects it from the customer at fulfillment — pay-at-window drive thru is the common case.
Payment state is carried by its own field on the order. It is not inferred from fulfillment_type, from the absence of payment details, or from any other field:
| Field | Type | Description |
|---|---|---|
unpaid | boolean | Set to true when payment has not been collected and is due at fulfillment. Omitted or false means the order is already paid. May only be true for supported fulfillment types (see the caution above). |
cash_amount_due | number | The amount for the merchant to collect at fulfillment, in the lowest denomination of the store's currency (e.g. cents). Only applies when unpaid is true. |
Submitting an Unpaid Order
- Set
fulfillment_typeto a type that supports unpaid submission —drive_thru, orpickup/deliveryif enabled for your integration by request. - Set
unpaidtotrue. - Set
cash_amount_dueto the amount the merchant should collect.
{
"type": "new_order",
"location_id": "YOUR_LOCATION_ID",
"order": {
"id": "1234567890",
"fulfillment_type": "drive_thru",
"unpaid": true,
"cash_amount_due": 3510,
"subtotal": 3280,
"tax": 230,
"tax_withheld": 0
}
}
Send cash_amount_due on every unpaid order. It is the amount surfaced to the merchant to collect, and it cannot be reliably derived from the order totals — it may be less than the order total when your platform funds a promotion or benefit that reduces the cash owed without being sent as a discounts line. For how the amount is interpreted and reconciled on the receiving side, see Cash Orders in the POS documentation.
Common Mistakes
- Relying on
fulfillment_type: "drive_thru"to mark the order unpaid. This is the most frequent cause of "our drive thru orders are reaching the POS as paid". The order is injected as paid, and staff are not prompted to collect payment at the window.unpaid: truemust be present on the order payload. - Omitting
cash_amount_dueon an unpaid order. The merchant then has no authoritative amount to collect for the order. - Setting
unpaid: trueon an unsupported fulfillment type. Only send it on a fulfillment type that is enabled for unpaid submission on your integration; contact the Stream team to havepickupordeliveryenabled.