Applies to: Orders API
Learn how to create, update, cancel, and split an order fulfillment.
A seller might add fulfillment information to an order when it's created or updated. They can use Square products or your Orders API-integrated application to manage their fulfillments.
Did you know?
If you want to track the progress of order fulfillments that are managed in a Square product, you should subscribe to Orders webhooks for notification of fulfillment events triggered outside of your application.
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 Orders API supports fulfillments of these types:
DELIVERY(Beta)PICKUPSHIPMENT(Beta)
- One fulfillment limit - Developers can add only one fulfillment to an order using the Orders API, either during or after creation.
- No fulfillment splitting - All items for an order created with the Orders API must be fulfilled at the same location.
- Limited delivery fulfillment support - Any order you create with the DELIVERY fulfillment type is not available to a seller and not shown in the Square Point of Sale unless you have a formal partnership agreement with Square. Please reach out to your Square Partner Manager to request Beta access. To become an app partner, submit a partnership request.
- Only paid orders are visible - Orders with fulfillments appear on Square products (such as the Square Dashboard and Point of Sale application) only after they're paid for. Sellers can then manage fulfillments for these orders using these Square products.
- Immutable fields - Most fulfillment fields are immutable based on the fulfillment
state. Editable fields include:state(if the order is being managed through a developer's application).pickup_detailsfields, such as thepickup_atornotefield.recipientfield, such asaddressorphone_number.shipment_detailsfields, such astracking_numberortracking_url.
A seller can create orders using your application or through Square products like Square Online. Orders retrieved by your application may have multiple fulfillments, which track the fulfillment of order line items across different seller locations.
For information about how a seller can create a multiple-fulfillment order using Square, see Manage cross location orders with Square for Retail.
Note
If your application retrieves a DELIVERY fulfillment order, it cannot access fulfillment delivery_details unless you are a Square partner developer and have signed up for the closed DELIVERY Beta. For more information, see DELIVERY type fulfillment.
If your application lets sellers see the state of any order fulfillments in their Square account, then it should handle cases where the Order.fulfillments array contains multiple items. While your application can only create single-fulfillment orders, it has access to fulfillment orders created by Square applications.
The following Order fragment shows a SHIPMENT Fulfillment:
{ "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. Other shipment_details fields are optional: carrier, shipping_note, shipping_type, tracking_number, and tracking_url.
As a SHIPMENT fulfillment order moves through stages, the fulfillment state is updated and corresponding timestamps are set:
in_progress_at- state changes toRESERVEDpackaged_at- state changes toPREPAREDshipped_at- state changes toCOMPLETEDcanceled_at- state changes toCANCELEDfailed_at- state changes toFAILED
This Order fragment shows a PICKUP Fulfillment scheduled for delivery ASAP but with a 30 minute prep time. Note the pickup_at time is 30 minutes after the order is created:
{ "order": { "id": "sfADX2Xqb8F4uZaFuAp3xlShefbZY", "location_id": "S8GWD5R9QB376", "line_items": [ … ], "fulfillments": [ { "type": "PICKUP", "state": "PROPOSED", "uid": "pickup1", "pickup_details": { "schedule_type": "ASAP", "prep_time_duration": "PT30M15S", "recipient": { "customer_id": "{{customer_id}}" } } } ], } }
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_typevalue determines the following:- If set to
SCHEDULED,pickup_atis required. - If set to
ASAP,prep_time_durationorpickup_atis required.
- If set to
- These fields can only be set while the order fulfillment
stateisPROPOSED:expires_at,auto_complete_duration,prep_time_duration, andschedule_type.
A scheduled order does not move to the 'Active' tab in Order Manager (and show up on a KDS or print from kitchen printers) until pickup time minus prep time. Although prep_time_duration is not required for the SCHEDULED type, Square recommends that your application sets the value. If a prep time is not provided, a seller using a KDS or kitchen printer might not know a SCHEDULED pickup is actionable until the time the buyer is supposed to arrive to pick up the order.
If the schedule_type is ASAP and the prep_time_duration is set then Square sets the pickup_at time to now plus prep_time_duration. If your application sets pickup_at for an ASAP pickup, prep_time_duration is ignored even if you've set that value too.
As a PICKUP fulfillment order moves through stages, the fulfillment state is updated and corresponding timestamps are set:
accepted_at- The state changes toRESERVEDready_at- The state changes toPREPAREDpick_up_at- The state changes toCOMPLETED.canceled_at- The state changes toCANCELEDrejected_at- The state changes toFAILED
This is a restricted (closed) Beta. You need to be a Square partner developer and have signed up for the closed DELIVERY Beta. Please reach out to your Square Partner Manager to request Beta access. To become an app partner, submit a partnership request.
Important
Requests to create a DELIVERY fulfillment order succeed with a 200 response even if you don't have a partnership agreement and are enrolled in the delivery beta program. However, the delivery order you create cannot be accessed by a seller and does not appear in the Square Order Manager.
This Order fragment shows a DELIVERY 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:
recipientdetails - Thedisplay_name,address, andphone_numberare required if there's no third-party managing delivery (managed_deliveryis set tofalse).schedule_type- It can be set toSCHEDULED(default) orASAP.deliver_at- Ifschedule_typeis set toASAP, this field is automatically set to the time the order is created plus theprep_time_duration. This field is required whenschedule_typeis 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_atanddelivery_window_durationidentifying the order delivery window. - Courier information (such as
courier_provider_name,courier_support_phone_number, and the combination ofcourier_pickup_atandcourier_pickup_window_durationidentifying 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_deliveryfield totrue. This makes the recipient information optional, such asdisplay_nameandaddress. - The
courier_provider_nameandcourier_support_phone_numberfields are required.
As an order moves through stages of fulfillment, the state of the fulfillment is updated and corresponding timestamps are set:
delivery_details.in_progress_at- The state changes toRESERVEDdelivery_details.ready_at- The state changes toPREPAREDdelivery_details.canceled_at- The state changes toCANCELEDdelivery_details.rejected_at- The state changes toFAILEDdelivery_details.completed_at- The state changes toCOMPLETED.
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
CreateOrderto create an order without a fulfillment.Create order
Call
UpdateOrderto update the order and add fulfillment details. The example adds thePICKUPtype 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.
Note
If you're attempting to update a fulfillment to set its state to COMPLETE, all payments on the order must already be complete. For information about completing payments on a order, see Using the Orders API PayOrder endpoint.
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 item is delivered
Before attempting to set a fulfillment.state to COMPLETED, the order must be paid for.
- If the
fulfillment.stateisn'tCOMPLETED:- Set
FulfillmentDeliveryDetails.delivered_atto the timestamp when delivery occurred. - Set
fulfillment.statetoCOMPLETED. - Set
order.statetoCOMPLETEDif no other fulfillments are pending and all payments on the order have been completed.
- Set
- If the
fulfillment.stateisCOMPLETED(this can happen if a seller marks it asCOMPLETEDafter they hand off the goods to the delivery service but before the delivery is completed):- The application can update
delivered_atafter a fulfillment is marked asCOMPLETEDbut before the orderstateisCOMPLETED. Ifdeliver_atcannot be updated, the application might save thedelivered_attimestamp as a note in theorder.fulfillments.delivery_details.notefield. - Set
order.statetoCOMPLETEDif no other fulfillments are pending and all payments on the order have been completed.
- The application can update
Fulfillment is canceled by the seller or delivery service
Specify the cancellation reason in the
FulfillmentDeliveryDetails.notesfield.Set
order.statetoCOMPLETEDif no other fulfillments are pending.Set
order.statetoCOMPLETEDorCANCELED. Note that you cannot setorder.statetoCANCELEDif:- 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.statecannot be set toCANCELEDif the order contains a completed fulfillment. The seller needs to perform a refund in Square Point of Sale if necessary after the order isCOMPLETED.
Fulfillment fails to complete
Specify a reason why the fulfillment failed in the
FulfillmentDeliveryDetails.notesfield.Set
fulfillment.statetoFAILED.Set
order.statetoCOMPLETEDif all payments on the order have been completed.Note that
order.statecannot be set toCANCELEDif 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, provide the Order object with the following information in the request body:
- The
versionof the order. - The
fulfillmentsarray identifying the fulfillment to be canceled. Provide the fulfillment UID being updated and set the value ofstatetoCANCELED.
Did you know?
An order cannot be canceled if its fulfillments are not in a CANCELED state.
A seller might split a fulfillment using Square products. The Orders API can retrieve these split fulfillments. For example, the Order.fulfillments object includes two fields (entries and line_item_application) that applications can use to determine which line items belong to which fulfillment.