Skip to main content

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.
The fulfillment type alone does not make an order unpaid

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: true on 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_address field to submit the delivery address details.

  • Populate the fulfillment_instructions field to submit the delivery instructions.

  • Populate the driver_tip with relevant tip information for driver.

  • Populate the delivery_fee and/or delivery_fee_taxes with 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_number field 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:

FieldTypeDescription
unpaidbooleanSet 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_duenumberThe 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

  1. Set fulfillment_type to a type that supports unpaid submission — drive_thru, or pickup / delivery if enabled for your integration by request.
  2. Set unpaid to true.
  3. Set cash_amount_due to 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: true must be present on the order payload.
  • Omitting cash_amount_due on an unpaid order. The merchant then has no authoritative amount to collect for the order.
  • Setting unpaid: true on 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 have pickup or delivery enabled.

See full new order payload.