In Shopify, the [`FulfillmentOrder`](/docs/api/admin-graphql/latest/objects/FulfillmentOrder) object models an end-to-end fulfillment process and is available in the GraphQL Admin API. The `FulfillmentOrder` object enables fulfillment data to sync accurately between Shopify and apps. > Deprecated: > By API version 2023-07, all apps should be using the [`FulfillmentOrder`](/docs/api/admin-graphql/latests/objects/FulfillmentOrder) object to manage fulfillments. > Apps using the following GraphQL Admin API objects to fulfill orders are using a legacy workflow that is no longer supported as of API version 2022-07: > > - [`Order`](/docs/api/admin-graphql/latest/objects/Order) > - [`Fulfillment`](/docs/api/admin-graphql/latest/objects/Fulfillment) This guide describes how to migrate your app to use fulfillment orders to manage fulfillments. ## Requirements - You've built an [order management](/docs/apps/build/orders-fulfillment/order-management-apps) or [fulfillment service](/docs/apps/build/orders-fulfillment/fulfillment-service-apps) app. - Your app is using the `Fulfillment` and `Order` API objects to fulfill orders, instead of the `FulfillmentOrder` object. > Note: > After the migration, `FulfillmentOrder` operations such as [`FulfillmentCreateV2`](/docs/api/admin-graphql/latest/mutations/fulfillmentCreateV2) are going to cancel pending/open legacy fulfillments and replace them. > > This will trigger update callbacks for the cancelled fulfillments. Consider the impact of receiving these callbacks before the migration. > > For example, you might want to avoid automatically performing actions when the legacy Fulfillment callbacks trigger. ## Step 1: Determine the permissions your app requires To migrate your app, you need to update your app's permissions. The permissions that you request depend on the [type of app](#types-of-apps) that you've built and the access to fulfillment orders associated with the [types of locations](#types-of-locations) that your app needs. ### Types of apps You can create the following types of apps: | Type of app | Permissions | |---|---| | [Order management app](/docs/apps/build/orders-fulfillment/order-management-apps) | | | [Fulfillment service app](/docs/apps/build/orders-fulfillment/fulfillment-service-apps) | Manage fulfillment orders assigned to locations belonging to the app: | > Note: > If an app combines the functions of an order management app and a fulfillment service, then the app should request all access scopes to manage all assigned and all unassigned fulfillment orders. ### Types of locations You can have the following types of locations on a shop: | Type of location | Description | |---|---| | Merchant-managed location | A location that's created by the merchant. | | Fulfillment service-managed location | A location that's created by a fulfillment service app.

When an app creates a [fulfillment service](/docs/api/admin-rest/latest/resources/fulfillmentservice), a new location is automatically created on the shop and associated with that fulfillment service. | ## Step 2: Update your app's permissions > Tip: If you [configure your app using Shopify CLI](/docs/apps/build/cli-for-apps/app-configuration), then your app will automatically use [Shopify managed installation](/docs/apps/build/authentication-authorization/app-installation). You can skip this step. When you've determined the additional permissions your app requires, you can update your app for [new installations](#new-installations) and [existing installations](#existing-installations). ### New installations For new installations, include the additional scopes in the permissions that your app requests as part of [authorization code grant](/docs/apps/build/authentication-authorization/access-tokens/authorization-code-grant). ### Existing installations - If your app has the `write_fulfillments` access scope, then it can request any of the following access scopes: `write_assigned_fulfillment_orders`, `write_merchant_managed_fulfillment_orders`, `write_third_party_fulfillment_orders`. - If your app has the `read_fulfillments` access scope, then it can request any of the following access scopes: `read_assigned_fulfillment_orders`,`read_merchant_managed_fulfillment_orders`, `read_third_party_fulfillment_orders`. - If your app has the `write_orders` access scope, and it doesn't have the `read_fulfillments` or `write_fulfillments` access scopes, it means that it's not a fulfillment service, and it doesn't own a dedicated location. As a result, it doesn't need the `read_assigned_fulfillment_orders` or `write_assigned_fulfillment_orders` access scopes. Instead, your app can request the `write_merchant_managed_fulfillment_orders` and `write_third_party_fulfillment_orders` access scopes. - If your app has the `read_orders` access scopes, and it doesn't have the `read/write_fulfillments` access scopes, then it can request the `write_merchant_managed_fulfillment_orders` and `write_third_party_fulfillment_orders` access scopes. > Caution: > If you have `read_fulfillments` but not `write_fulfillments` permission, then you can request only the `read_*` scopes. ## Step 3: Opt in to fulfillment orders as a fulfillment service Legacy fulfillment services are different from fulfillment services that use fulfillment orders in the following ways: - Shopify doesn't automatically create pending fulfillments for the fulfillment service when fulfillment is requested. - Shopify creates successful fulfillments instead of pending fulfillments for the fulfillment service when a fulfilled order is imported. The communication pattern between Shopify and the app has changed, and no longer relies on `fulfillment/create` webhooks. Instead, the communication relies on explicit POSTs to the callback URL and the callback URL handles all fulfillment and cancellation requests. Before a fulfillment service can switch to the fulfillment order-based workflow, the fulfillment service should be updated to register a callback URL and to implicitly switch to the new workflow. You can use the GraphQL Admin API's [`fulfillmentServiceUpdate`](/docs/api/admin-graphql/latest/mutations/fulfillmentserviceupdate) mutation for setting `callback_url` and `fulfillment_orders_opt_in` values:

After you've opted in to the fulfillment order-based workflow, the fulfillment service app should act as it's described in [Manage fulfillments as a fulfillment service app](/docs/apps/build/orders-fulfillment/fulfillment-service-apps/build-for-fulfillment-services) section. > Note: > Unless granting the API permissions, order management apps don't need any additional pre-configuration to switch to the fulfillment order based APIs, or to temporarily rollback to the legacy fulfillment workflow. ## Step 4: Manage fulfillments using fulfillment orders After you've updated your app, and opted in legacy fulfillment services to use fulfillment orders, you can start managing fulfillments using fulfillment orders as an [order management app](/docs/apps/build/orders-fulfillment/order-management-apps/build-fulfillment-solutions) or a [fulfillment service app](/docs/apps/build/orders-fulfillment/fulfillment-service-apps/build-for-fulfillment-services). ## Next steps - Learn more about [the benefits of adopting fulfillment orders workflows](https://www.shopify.com/ca/partners/blog/shopify-fulfillment-orders-api). - Manage fulfillments as an [order management app](/docs/apps/build/orders-fulfillment/order-management-apps/build-fulfillment-solutions). - Manage fulfillments as a [fulfillment service app](/docs/apps/build/orders-fulfillment/fulfillment-service-apps/build-for-fulfillment-services). - Learn about the recommended workflow for using the GraphQL Admin API to track orders placed through [third-party marketplaces](/docs/apps/build/orders-fulfillment/order-management-apps/track-orders-other-platforms).