Build for fulfillment services
Fulfillment service apps can provide third-party warehousing, print on demand, or fulfillment services that prepare and ship orders on behalf of merchants.
This guide describes how to use the GraphQL Admin API to manage fulfillments in the following ways:
- Receive fulfillment requests and cancellations
- Accept and reject fulfillment requests and cancellations
- Exchange fulfillment requests notes with merchants
- Create and perform fulfillments for assigned work
- Optionally close fulfillment orders
Requirements
Anchor link to section titled "Requirements"- Your app can make authenticated requests to the GraphQL Admin API.
- Your app has the
write_fulfillments
,read_assigned_fulfillment_orders
andwrite_assigned_fulfillment_orders
access scopes. Learn how to configure your access scopes using Shopify CLI. - Your store has existing orders that are unfulfilled. If you need to make changes to an unfulfilled item, then you can edit an order.
- You've met Shopify's protected customer data requirements.
Step 1: Create a fulfillment service
Anchor link to section titled "Step 1: Create a fulfillment service"To begin managing fulfillments as a fulfillment service app, you need to create a fulfillment service in Shopify with a callback URL that will listen for fulfillment requests. A fulfillment service needs to opt in to fulfillment orders by letting Shopify know that they’re ready to perform fulfillment order-based fulfillment rather than order-based fulfillment.
You can use the GraphQL Admin API's fulfillmentServiceCreate
mutation to register a callback URL and opt in a fulfillment service to use fulfillment orders.
To register a fulfillment service, your app requires the write_fulfillments
access scope.
Step 2: Receive fulfillment requests and cancellations
Anchor link to section titled "Step 2: Receive fulfillment requests and cancellations"Apps must configure an endpoint on a callback URL where Shopify will send the notifications for fulfillment requests. This is a requirement to receive requests from Shopify. The endpoint should be structured in the following format: <callback_url>/fulfillment_order_notification
.
The payloads that the endpoint receives include the kind
property or field, which can have one of the following values:
Value | Description |
---|---|
FULFILLMENT_REQUEST |
When a merchant requests a fulfillment in their Shopify admin |
CANCELLATION_REQUEST |
When a merchant submits a cancellation request in their Shopify admin |
The following examples show payloads for each type of request:
Step 3: Act on fulfillment requests
Anchor link to section titled "Step 3: Act on fulfillment requests"Each fulfillment order has a status and a request status, both of which indicate the state of the fulfillment order.
A fulfillment order notification of FULFILLMENT_REQUEST
indicates that there’s a new fulfillment order assigned to the service, and it’s ready to be acted on because the merchant has requested a fulfillment.
Fulfillment services can retrieve assigned fulfillment order requests, and specify the fields that are required to determine whether it should accept or reject a fulfillment request. Requests can be validated with the same HMAC validation method that's used when Shopify sends webhooks to apps.
Retrieve assigned fulfillment order requests
Anchor link to section titled "Retrieve assigned fulfillment order requests"The following example shows to use the assignedFulfillmentOrders
connection to request the first 10 assigned fulfillment orders with the FULFILLMENT_REQUESTED
status:
- The fulfillment order destination, line items, and line item SKUs are included as part of the request.
- The query contains the
merchantRequests
field, which includes any notes that the merchant provided when they submitted the request.
Accept a fulfillment request
Anchor link to section titled "Accept a fulfillment request"After retrieving the assigned fulfillment orders, the fulfillment service can review each fulfillment order, and determine whether it can be fulfilled.
To accept a fulfillment order, the fulfillment service must send an accepted request using the GraphQL Admin API's fulfillmentOrderAcceptFulfillmentRequest
mutation:
After the fulfillment service sends an accepted request, the fulfillment order card in the Shopify admin indicates to the merchant that the request was accepted:
Reject a fulfillment request
Anchor link to section titled "Reject a fulfillment request"If the fulfillment service determines that it can’t fulfill the order, then it can reject the fulfillment request using the fulfillmentOrderRejectFulfillmentRequest mutation:
After the fulfillment service sends a rejected request, the fulfillment order card in the Shopify admin indicates to the merchant that the request was rejected:
Step 4: Create fulfillments
Anchor link to section titled "Step 4: Create fulfillments"After accepting a fulfillment request, the fulfillment service can begin creating fulfillments using the GraphQL Admin API's fulfillmentCreateV2
mutation. The fulfillment service can create multiple fulfillments for a given fulfillment order if required, representing multiple packages to be shipped.
When an app accepts a fulfillment request, the fulfillment order status transitions to in progress. After all line items on the fulfillment order are entirely fulfilled, the fulfillment order status transitions to a closed state.
The following examples show how to create a fulfillment for a single line item, with a quantity of three. The response provides a success status, which indicates that the fulfillment has been successfully created.
Step 5: Act on cancellation requests
Anchor link to section titled "Step 5: Act on cancellation requests"A fulfillment order notification of CANCELLATION_REQUEST
indicates that a merchant has requested for a fulfillment order to be cancelled. Similar to retrieving assigned fulfillment order requests, the fulfillment service can retrieve cancellation requests.
After retrieving cancellation requests, the fulfillment service can either accept or reject the cancellation request. If the fulfillment service accepts the cancellation request, then it can cancel the fulfillment.
Merchants cancelling fulfillment orders
Anchor link to section titled "Merchants cancelling fulfillment orders"Merchants can cancel a fulfillment order before the fulfillment service responds to the cancellation request. This option is provided immediately after requesting cancellation. A warning message is also displayed to the merchant, indicating that forcibly cancelling a fulfillment order doesn’t guarantee that the fulfillment service won't ship the items.
After the fulfillment service responds by either rejecting or accepting the cancellation request, the option is no longer provided to the merchant. The fulfillment service can’t create fulfillments against a fulfillment order that was cancelled by a merchant.
Retrieve cancellation requests
Anchor link to section titled "Retrieve cancellation requests"The following example shows how to use the assignedFulfillmentOrders
connection to query cancellation requests. Pass in the assignmentStatus
argument and set it to CANCELLATION_REQUEST
to retrieve assigned fulfillment orders with the CANCELLATION_REQUEST
status.
Accept a cancellation request
Anchor link to section titled "Accept a cancellation request"After retrieving the assigned fulfillment order cancellation requests, the fulfillment service can review each fulfillment order, and determine whether it can be cancelled.
If the fulfillment order can be cancelled, then the fulfillment service can use the GraphQL Admin API's fulfillmentOrderAcceptCancellationRequest
mutation to accept the cancellation of the fulfillment order and send an optional message to the merchant.
The response returns a fulfillment order that has a request status of cancellation accepted:
After the fulfillment service accepts a cancellation request, the fulfillment order card in the Shopify admin indicates to the merchant that the cancellation request was accepted:
Reject a cancellation request
Anchor link to section titled "Reject a cancellation request"If the fulfillment service determines that it can’t accept the cancellation of the fulfillment order, then it can reject the cancellation request using the the GraphQL Admin API's fulfillmentOrderRejectCancellationRequest
mutation.
The response returns a fulfillment order that has a request status of cancellation rejected. The fulfillment service can continue to create fulfillments after rejecting a cancellation.
After the fulfillment service rejects a cancellation request, the fulfillment order card in the Shopify admin indicates to the merchant that the cancellation request was rejected:
Step 6: Cancel a fulfillment
Anchor link to section titled "Step 6: Cancel a fulfillment"You can cancel a fulfillment using the GraphQL Admin API's fulfillmentCancel
mutation. However, any fulfillment orders that the fulfillment was created against will be affected in the following ways:
- If the underlying fulfillment order was entirely fulfilled, then it will be automatically closed.
- After cancelling a fulfillment, a new fulfillment order is created consisting of the line items from the cancelled fulfillment. This new fulfillment order is assigned to the same location as the original fulfillment order if the items are still stocked there.
- If all items from the cancelled fulfillment can't be sourced from the same location, then the new fulfillment order is assigned to a location where the items are stocked, considering the shop’s fulfillment priority settings. This might result in multiple newly opened fulfillment orders for different locations.
- If the fulfillment order was partially fulfilled, then the fulfillment order line item and remaining quantity properties / fields are adjusted back based on the cancelled fulfillment’s line items.
After a fulfillment service cancels a fulfillment, the fulfillment order card in the Shopify admin notifies the merchant that the fulfillment request has been cancelled:
Step 7 (Optional): Close a fulfillment order
Anchor link to section titled "Step 7 (Optional): Close a fulfillment order"In some cases, a fulfillment service might realize that it can’t fulfill the requested items only after it’s already accepted a fulfillment order request.
The fulfillment service can use the GraphQL Admin API's fulfillmentOrderClose
mutation to close the fulfillment order and indicate to the merchant that they won't be fulfilling the order.
Closing a fulfillment results in a fulfillment order where the status is incomplete and the request status is closed.
Step 8 (Optional): Enable tracking support
Anchor link to section titled "Step 8 (Optional): Enable tracking support"Your app can optionally act on Shopify requests for tracking numbers by exposing a /fetch_tracking_numbers
endpoint that's prefixed with the callback_url
that you set in step 2.
If tracking_support
is set to true
, then once each hour, Shopify makes a request to the /fetch_tracking_numbers
endpoint to determine if there are any completed fulfillments awaiting tracking numbers from the remote fulfillment service.
Step 9 (Optional): Share inventory levels with Shopify
Anchor link to section titled "Step 9 (Optional): Share inventory levels with Shopify"Your app can optionally act on Shopify requests for inventory levels by exposing a /fetch_stock
endpoint that's prefixed with the callback_url
that you set in step 2.
If fulfillment_service.inventory_management
is set to true
, then Shopify makes a request to the /fetch_stock
endpoint for the inventory of an individual SKU when the product is set up initially, when its SKU is changed in the Shopify admin, or when its inventory management is set to use the fulfillment service. Please note that SKU strings are case-sensitive at Shopify, and the SKUs returned from the /fetch_stock
endpoint will be matched to the Shopify product SKUs respecting the case.
A request for all inventory data happens once every hour to keep Shopify up to date with the remote fulfillment service.
The format for the payload is a JSON object where the keys are the SKUs and the values are the on_hand
inventory state levels.
In API version 2023-01 and higher, your app can subscribe to webhooks for event notifications related to fulfillment orders. The following examples show the JSON responses from each of the available webhooks.
To learn how to set up and consume webhooks, refer to Webhooks configuration overview.
- Learn about the recommended workflow for using Shopify APIs to track orders placed through third-party marketplaces.
- Learn how to manage inventory using the GraphQL Admin API by referring to the
inventoryItem
query andinventoryActivate
mutation in the reference documentation.