A seller can optionally add fulfillment information to an order when it's created or after it's created. Sellers can use Square products or custom applications using the Orders API to manage fulfillments.
The Orders API supports creating and managing fulfillments of these types:
SHIPMENT
PICKUP
DELIVERY
(Beta)
Note
This is a closed Beta. Request Beta access by completing the participation survey.
Beta access to the DELIVERY
fulfillment type is for use cases other than performing deliveries on behalf of sellers. Developers seeking to perform deliveries on behalf of sellers need a formal partnership agreement. To become an app partner, submit a partnership request.
An order can have one or more fulfillments, as described in the following examples:
- Suppose a customer in a gardening store buys flowers and a large bag of dirt. The customer takes the flowers immediately but chooses to pick up the dirt later in the day. In this case, the seller creates two fulfillments of the
PICKUP
type. - Suppose a customer orders a shirt and two pairs of shoes (brown shoes and black shoes). Now suppose the brown shoes aren't in stock. The seller might choose to ship the brown shoes at a later date. In this case, the order has two fulfillments.
If an order has multiple fulfillments, they must be of the same fulfillment type.
The Orders API stores fulfillment information in the Order.fulfillments field (an array of Fulfillment objects). Each Fulfillment
includes the following:
uid
- A Square-assigned unique identifier.type
- The type of fulfillment.state
- Initially, the fulfillment state isPROPOSED
.- Fulfillment details - Depending on the
type
, fulfillment details are stored in pickup_details, shipment_details, or delivery_details.
The following Order
fragment shows a single fulfillment (see Fulfillment) of the SHIPMENT
type:
{
"order": {
"id": "uuVIIBP9Nl8L7xq6MJQayNuo8LdZY",
"location_id": "S8GWD5R9QB376",
"line_items": [
…
],
"fulfillments": [
{
"type": "SHIPMENT",
"shipment_details": {
"recipient": {
"display_name": "John Doe"
}
}
}
]
}
}
The recipient.display_name
is the only shipment_details field required when a fulfillment is created. The following apply for the other shipment_details
fields:
Applications can provide other optional
shipment_details
(either when a fulfillment is created or later usingUpdateOrder
), such ascarrier
,shipping_note
,shipping_type
,tracking_number
, andtracking_url
.Some of the timestamp fields are automatically set as the order fulfillment
state
changes. For example:- The
packaged_at
timestamp is set when the fulfillmentstate
changes toPREPARED
. - The
shipped_at
timestamp is set when the fulfillmentstate
changes toCOMPLETED
. - The
canceled_at
timestamp is set when the fulfillmentstate
changes toCANCELED
. - The
failed_at
timestamp is set when the fulfillmentstate
changes toFAILED
. - The
in_progress_at
timestamp is set when the fulfillmentstate
changes toRESERVED
.
- The
The following Order
fragment shows a single fulfillment (see Fulfillment) of the PICKUP
type:
{ "order": { "id": "sfADX2Xqb8F4uZaFuAp3xlShefbZY", "location_id": "S8GWD5R9QB376", "line_items": [ … ], "fulfillments": [ { "uid": "Beryz5QiHAwIfvFzBpYQ", "type": "PICKUP", "state": "PROPOSED", "pickup_details": { "pickup_at": "2016-05-21T23:59:33.123Z", "recipient": { "display_name": "John Doe" } } } ], … } }
The pickup_at
and recipient.display_name
fields are the only pickup_details fields required when creating a fulfillment. The following apply for the other pickup_details
fields:
- The
schedule_type
value determines the following:- If set to
SCHEDULED
,pick_up_at
is required. - If set to
ASAP
,prep_time_duration
is required.
- If set to
- These fields can only be set while the order fulfillment
state
isPROPOSED
:expires_at
,auto_complete_duration
,prep_time_duration
, andschedule_type
. - Some of the timestamp fields are automatically set as the order fulfillment
state
changes. For example:- The
accepted_at
timestamp is set when the fulfillmentstate
changes toRESERVED
. - The
ready_at
timestamp is set when the fulfillmentstate
changes toPREPARED
. - The
pick_up_at
timestamp is set when the fulfillmentstate
changes toCOMPLETED
. - The
canceled_at
timestamp is set when the fulfillmentstate
changes toCANCELED
. - The
rejected_at
timestamp is set when the fulfillmentstate
changes toFAILED
.
- The
The following Order
fragment shows a DELIVERY
type fulfillment:
{ "order":{ "id":"MgVVrx8GhOy4K7LO7LtYwgM3RUaZY", "location_id":"7WQ0KXC8ZSD90", "line_items":[ { ... } ], "fulfillments":[ { "uid":"uYJmomsp8OjA2iY8PZR2IC", "type":"DELIVERY", "state":"PROPOSED", "delivery_details":{ "recipient":{ "display_name":"John Doe", "phone_number":"2065129261", "address":{ "address_line_1":"111 Maple", "locality":"Seattle" } }, "deliver_at":"2022-05-25T20:59:33.123Z" } } ] ... "state":"OPEN", "version":1, ... } }
Note the following about delivery_details:
The following information is required when creating a delivery fulfillment:
recipient
details - Thedisplay_name
,address
, andphone_number
are required if there's no third-party managing delivery (managed_delivery
is set tofalse
).schedule_type
- It can be set toSCHEDULED
(default) orASAP
.deliver_at
- Ifschedule_type
is set toASAP
, this field is automatically set to the time the order is created plus theprep_time_duration
. This field is required whenschedule_type
is set toSCHEDULED
.
Applications can provide optional
delivery_detail
information, such as:prep_time_duration
. The time it takes to prepare and deliver the fulfillment.- A combination of
deliver_at
anddelivery_window_duration
identifying the order delivery window. - Courier information (such as
courier_provider_name
,courier_support_phone_number
, and the combination ofcourier_pickup_at
andcourier_pickup_window_duration
identifying the courier pickup window). - Other information (such as optional drop-off notes and whether the delivery is a no-contact delivery).
For a delivery managed by a third party:
- Set the
managed_delivery
field totrue
. This makes the recipient information optional, such asdisplay_name
andaddress
. - The
courier_provider_name
andcourier_support_phone_number
fields are required.
- Set the
Some of the timestamp fields are automatically set as the order fulfillment
state
changes. For example:- The
delivery_details.in_progress_at
timestamp is set when the fulfillmentstate
changes toRESERVED
. - The
delivery_details.canceled_at
timestamp is set when the fulfillmentstate
changes toCANCELED
. - The
delivery_details.rejected_at
timestamp is set when the fulfillmentstate
changes toFAILED
. - The
delivery_details.ready_at
timestamp is set when the fulfillmentstate
changes toPREPARED
. - The
delivery_details.completed_at
timestamp is set when the fulfillmentstate
changes toCOMPLETED
.
- The
Orders with fulfillments appear on Square products (such as the Seller Dashboard and Point of Sale application) only after they're paid for. Sellers can then manage fulfillments for these orders using these Square products.
Developers can add only one fulfillment to an order using the Orders API, either during or after creation.
The Orders API doesn't support splitting a fulfillment. A seller can optionally split a fulfillment using Square products and applications can view these split fulfillments. For example, the Order.fulfillments object includes two fields (
entries
andline_item_application
) that applications can use to determine which line items belong to which fulfillment.Some fulfillment fields can be updated based on the fulfillment
state
. Some fulfillment fields are immutable. In general, developers can use the Orders API to apply limited fulfillment updates, such as:- Updating the
state
(if the order is being managed through a developer's application rather than Square Order Manager). - Updating pickup details, such as the
pickup_at
ornote
field. - Updating recipient details, such as
address
orphone_number
. - Updating shipment details, such as
tracking_number
ortracking_url
.
- Updating the
Applications can use the Orders API to create a fulfillment of the
SHIPMENT
,PICKUP
, andDELIVERY
types.Currently, only Square Online supports creating fulfillments of the
DELIVERY
type; other Square products (such as the Seller Dashboard and Point of Sale) don't. When applications retrieve an order using the Orders API, they see theDELIVERY
fulfillment type, but they don't see other delivery details of the fulfillment.All fulfillments in an order are the same type. When a seller splits a fulfillment, both fulfillments are of the same type. To change the fulfillment type, you must first move the fulfillment to the
CANCELED
state and then add another fulfillment of the type you want.
Applications can create an order with fulfillment or first create an order and later update the order to include fulfillment.
This example is a CreateOrder request that creates an order for four sandwiches. The order includes fulfillment details. The order type is a PICKUP
order and the customer, John Doe, has selected curbside pickup at a specific time.
Create order
The following is an example response fragment:
{ "order": { "id": "sfADX2Xqb8F4uZaFuAp3xlShefbZY", "location_id": "S8GWD5R9QB376", "line_items": [ { "uid": "U0PzEdJgoOPWE7AxvCRldC", "quantity": "4", "name": "Sandwich", "base_price_money": { "amount": 1500, "currency": "USD" }, "note": "ad hoc item", "gross_sales_money": { "amount": 6000, "currency": "USD" }, … ], "fulfillments": [ { "uid": "VnDwb1Yu42mMjrPEWHLYW", "type": "PICKUP", "state": "PROPOSED", "pickup_details": { "pickup_at": "2022-02-12T23:00:00.000Z", "recipient": { "display_name": "John Doe", "phone_number": "111-111-1111" }, "is_curbside_pickup": true } } ], … } }
In this example, you create an order and then update the order to add fulfillment. Note that you cannot add a fulfillment if the order state
is COMPLETED
.
Call
CreateOrder
to create an order without a fulfillment.Create order
Call
UpdateOrder
to update the order and add fulfillment details. The example adds thePICKUP
type fulfillment to the order.Update order
Note
To view the fulfillments for an existing order, call RetrieveOrder. The fulfillments appear in the Order.fulfillments object of the RetrieveOrder response.
In the current implementation, there are limitations to updating fulfillments using the Orders API. For more information, see Guidelines and limitations.
Suppose you created an order for an ad hoc item. The following UpdateOrder
example updates the fulfillment state, recipient display name, pickup detail note, and recipient display name:
Update order
The following is an example response fragment:
{ "order": { "id": "sfADX2Xqb8F4uZaFuAp3xlShefbZY", "location_id": "S8GWD5R9QB376", "line_items": [ { … } ], "fulfillments": [ { "uid": "VnDwb1Yu42mMjrPEWHLYW", "type": "PICKUP", "state": "PREPARED", "pickup_details": { "pickup_at": "2022-02-12T23:00:00.000Z", "note": "updated note", "accepted_at": "2022-02-26T00:24:07.316Z", "ready_at": "2022-02-26T00:24:07.316Z", "recipient": { "display_name": "Jane Doe", "phone_number": "111-111-1111" }, "is_curbside_pickup": true } } ], … "version": 2, } }
A DELIVERY
type fulfillment completes when the items are delivered to the buyer. However, there are times when a seller (or deliver service) cancels the fulfillment or the fulfillment fails to complete. The following are the suggested best practices for an application to update an order as the DELIVERY
type fulfillment progresses:
Fulfillment completes successfully:
- If the
fulfillment.state
isn'tCOMPLETED
:- Set
FulfillmentDeliveryDetails.delivered_at
to the timestamp when delivery occurred. - Set
fulfillment.state
toCOMPLETED
. - Set
order.state
toCOMPLETED
if no other fulfillments are pending.
- Set
- If the
fulfillment.state
isCOMPLETED
(this can happen if a seller marks it asCOMPLETED
after they hand off the goods to the delivery service but before the delivery is completed):- The application can update
delivered_at
after a fulfillment is marked asCOMPLETED
but before the orderstate
isCOMPLETED
. Ifdeliver_at
cannot be updated, the application might save thedelivered_at
timestamp as a note in theorder.fulfillments.delivery_details.note
field. - Set
order.state
toCOMPLETED
if no other fulfillments are pending.
- The application can update
- If the
The seller or delivery service cancels the fulfillment:
Specify the cancellation reason in the
FulfillmentDeliveryDetails.notes
field.Set
order.state
toCOMPLETED
if no other fulfillments are pending.Set
order.state
toCOMPLETED
orCANCELED
. Note that you cannot set order state to CANCELED if:- A completed payment exists on the order.
- The order contains a completed fulfillment. The seller needs to perform a refund in Square Point of Sale if necessary after the order is COMPLETED.
Note that
order.state
cannot be set toCANCELED
if the order contains a completed fulfillment. The seller needs to perform a refund in Square Point of Sale if necessary after the order isCOMPLETED
.
A fulfillment fails to complete:
Specify a reason why the fulfillment failed in the
FulfillmentDeliveryDetails.notes
field.Set
fulfillment.state
toFAILED
.Set
order.state
toCOMPLETED
.Note that
order.state
cannot be set toCANCELED
if the order contains a completed fulfillment. The seller needs to perform a refund in Square Point of Sale if necessary after the order isCOMPLETED
.
You cannot delete a fulfillment from an order. You can only cancel a fulfillment using the UpdateOrder
endpoint as shown:
curl https://connect.squareupsandbox.com/v2/orders/{ORDER_ID} \
-X PUT \
-H 'Square-Version: 2022-09-21' \
-H 'Authorization: Bearer {ACCESS_TOKEN}' \
-H 'Content-Type: application/json' \
-d '{
"idempotency_key": "{UNIQUE_KEY}",
"order": {
"version": 2,
"fulfillments": [
{
"uid": "{FULFILLMENT_UID}",
"state": "CANCELED"
}
]
}
}'
In the request, you provide the Order
object with the following information in the request body:
- The
version
of the order. - The
fulfillments
array identifying the specific fulfillment. You provide the fulfillment UID being updated and specify the value of thestate
field asCANCELED
.