Fulfillment orders migration guide

Using the FulfillmentOrder resource instead of using the Fulfillment and Order resources separately gives you more control over the ways that you can manage fulfillments. Using the Fulfillment and Order resources to fulfill orders is considered legacy behavior, and is not compatible with modern workflows. All clients should be using Fulfillment Orders to manage fulfillment. Fulfillment Orders also provide the following benefits:

  • You can fetch the assigned location of a given group of unfulfilled line items to determine where fulfillment should occur.
  • You no longer need to match SKUs or filter out the items on an order that don’t apply to you before you can determine which items you need to fulfill.
  • Merchants and apps can add notes to requests to improve communication throughout the fulfillment process.
  • The process of making fulfillment and cancellation requests is formalized.

To migrate your app to managing fulfillments with the FulfillmentOrder resource, you need to request some additional permissions. The permissions that you need to request differ based on the type of app that you build.

For existing installations, you can request the additional permissions without the merchant needing to reinstall your app.

Update your app's permissions

  1. Determine which additional permissions you need to request. These differ depending on the type of app that you build.
  • Permissions for fulfillment service apps:

    • read and write permissions for write_assigned_fulfillment_orders to manage fulfillment orders assigned to their location
  • Permissions for order management apps:

    • read or write permissions for merchant_managed_fulfillment_orders to manage fulfillment orders assigned to merchant-managed locations
    • read or write permissions for third_party_fulfillment_orders to manage third-party fulfillment orders on behalf of the merchant
  1. For new installations, include the additional scopes in the permissions that your app requests as part of the OAuth process.
  2. For existing installations, use the /admin/request_granular_access_scopes endpoint described below to request the additional scopes without merchants reinstalling your app.

Requesting additional scopes for existing installations

For existing installations of your app, you don't need to ask merchants to agree to new permissions if they have already granted read_fulfillments or write_fulfillments. Instead, you can use the following endpoint to request a subset of granular access scopes for an individual shop installation.

If you have read_fulfillments but not write_fulfillments, then you can request only the read_* scopes.

POST /admin/request_granular_access_scopes.json

Adds granular versions of an existing access scope to an existing installation. In the body of your request, you should include an array of the scopes from the list below:

  • read_assigned_fulfillment_orders
  • read_merchant_managed_fulfillment_orders
  • read_third_party_fulfillment_orders
  • write_assigned_fulfillment_orders
  • write_merchant_managed_fulfillment_orders
  • write_third_party_fulfillment_orders

Add a single granular access scope to an existing installation

POST /admin/request_granular_access_scopes.json
{
  "requested_scopes": [
    "write_assigned_fulfillment_orders"
  ]
}
View Response
HTTP/1.1 200 OK
{
  "access_scopes": [
    {
      "handle": "write_fulfillments"
    },
    {
      "handle": "write_assigned_fulfillment_orders"
    }
  ]
}

Once you've gained access to the appropriate scopes, you can start managing fulfillments using Fulfillment Orders as an order management app or a fulfillment service app

Fulfillment Service Migration

There are some differences between legacy fulfillment services and fulfillment services using fulfillment orders. These differences are:

  • Shopify won't automatically create pending fulfillments for the fulfillment service when fulfillment is requested.
  • Shopify will create successful fulfillments instead of pending fulfillments for the fulfillment service when a fulfilled order is imported.

The communication pattern between Shopify and the app changes, no longer relying on fulfillment/create webhooks, but rather on explicit POSTs to the callback URL. This callback URL handles all fulfillment and cancellation requests. This URL can be registered by using the fulfillmentServiceUpdate mutation in GraphQL.

Before opting into FulfillmentOrder-based fulfillment, your app must meet the following requirements:

  • All assigned fulfillments must be completed (none in PENDING or OPEN states).

As an emergency roll-back measure, you can opt out FulfillmentOrder-based fulfillment after you’ve opted in. But before you can do so, your app must meet the following requirements:

  • All fulfillment requests must be rejected
  • All cancellation requests must be accepted
  • All in-progress fulfillment orders that were previously accepted must either have their fulfillment orders closed or their fulfillments created

If the assignedFulfillmentOrders query doesn’t return any results, then you should be able to opt out of FulfillmentOrder-based fulfillment. Opting out of FulfillmentOrder-based fulfillment is only recommended on a temporary basis.