An exchange represents the intent of a buyer to swap one or more items from an order for different items from the same merchant or a third-party fulfillment location. Merchants can manage their exchanges in Shopify, and exchanges apps can take actions on behalf of merchants.
This guide shows you how to manage exchanges using the GraphQL Admin API.
## Requirements
- Your app can make [authenticated requests](/docs/api/admin-graphql#authentication) to the GraphQL Admin API.
- Your app has the `read_returns` and `write_returns` [access scopes](/docs/api/usage/access-scopes). Learn how to [configure your access scopes using Shopify CLI](/docs/apps/build/cli-for-apps/app-configuration).
- Your store has existing [orders](/docs/api/admin-graphql/latest/objects/Order) that have been fulfilled. You can return only items that have been fulfilled. If you need to make changes to an unfulfilled item, then you can [edit an order](/docs/apps/build/orders-fulfillment/order-management-apps/edit-orders).
- You're using API version `2024-07` or higher.
- You've met Shopify's [protected customer data requirements](/docs/apps/launch/protected-customer-data).
## Step 1: Query returnable fulfillments
Exchanges are applied to a returnable fulfillment. A returnable fulfillment is an order that has been delivered and is eligible to be returned to the merchant or third-party fulfillment service.
To retrieve the fulfillment line items that can be returned in an order, provide the ID of the order in the [`returnableFulfillments`](/docs/api/admin-graphql/latest/queries/returnableFulfillments) query. The response returns the fulfillment line item ID, which you'll use as input to [create a return](#step-3-create-a-return-with-exchanges).
> Tip:
> You can retrieve the ID of an order using the [`orders` query](/docs/api/admin-graphql/latest/queries/orders).
## Step 2 (Optional): Calculate return financials with exchanges
You can use the [`returnCalculate`](/docs/api/admin-graphql/latest/queries/returnCalculate) query to calculate financial data for an exchange with given inputs. The query doesn't create the return or the exchange. It only calculates the financial impact of a return if the return was created with the same inputs. Exchange line items are sent as input, alongside the return line items.
## Step 3: Create a return with exchanges
You can create a return from an existing order that has at least one fulfilled line item that hasn't yet been refunded. If you create a return on an [archived order](https://help.shopify.com/manual/orders/cancel-delete-order#archive-orders-manually), then the order is automatically unarchived.
The [`returnCreate`](/docs/api/admin-graphql/latest/mutations/returnCreate) mutation with exchange line items input does the following:
- Creates a return in the `OPEN` state, and assumes that the return request from the customer has already been approved. You should only create a return if the merchant's intent is to [approve a customer’s return request](/docs/apps/build/orders-fulfillment/returns-apps/build-return-management/#approve-a-request).
- Creates a [reverse fulfillment order](/docs/apps/build/orders-fulfillment/returns-apps/manage-reverse-fulfillment-orders), and enables you to create a [reverse delivery](/docs/apps/build/orders-fulfillment/returns-apps/manage-reverse-deliveries) for the reverse fulfillment order
- Creates a sales agreement with a `RETURN` reason, which links to all sales created for the return or exchange
- Creates sales records that reverse the sales records for the items being returned
- Creates sales records for any exchange line items
- Places the fulfillment order with the exchange line items on hold
When a return is created with exchange items, the exchange items will create fulfillment orders with an `ON_HOLD` status and `AWAITING_RETURN_ITEMS` as the fulfillment hold reason. For more information on managing fulfillments, refer to [build for fulfillments services](/docs/apps/build/orders-fulfillment/fulfillment-service-apps/build-for-fulfillment-services).
> Note:
> If you create a return with an exchange, then the fulfillment order with the exchange line items will be automatically placed on hold.
## Step 4 (Optional): Collect payment for the exchange
If a balance is due on the exchange, then you can use the [`orderInvoiceSend`](/docs/api/admin-graphql/latest/mutations/orderInvoiceSend) mutation to send an updated invoice to the customer prior to releasing the hold on the exchange.
## Step 5: Query for the ID of the fulfillment order on hold
To fulfill the item for the exchange, you need to release the hold on the fulfillment order by querying for the ID of the fulfillment order that contains the hold.
To retrieve the fulfillment order ID, provide the ID of the order in the [`order`](/docs/api/admin-graphql/latest/queries/order) query. The response returns the `fulfillmentOrders` which you can filter to locate the fulfillment order with a `status` of `ON_HOLD` and a `fulfillmentHold` with a `reason` of `AWAITING_RETURN_ITEMS`. You'll use the ID of that `fulfillmentOrder` to [release the hold](#step-6-release-the-hold-in-order-to-fulfill-the-item) in the next step.
## Step 6: Release the hold in order to fulfill the item
After a payment has been received, you can use the [`fulfillmentOrderReleaseHold`](/docs/api/admin-graphql/latest/mutations/fulfillmentOrderReleaseHold) mutation to release the item for the exchange so that it can be fulfilled.
# Step 7: Fulfill the item
After the hold has been released, you can fulfill the item using the [`fulfillmentOrderSubmitFulfillmentRequest`](/docs/api/admin-graphql/latest/mutations/fulfillmentOrderSubmitFulfillmentRequest) or [`fulfillmentCreateV2` mutation](/docs/api/admin-graphql/latest/mutations/fulfillmentCreateV2) mutation.
## Next steps
- Learn how to [preview and refund duties](/docs/apps/build/orders-fulfillment/returns-apps/view-and-refund-duties) with the GraphQL Admin API.
- Learn how to [manage reverse fulfillment orders](/docs/apps/build/orders-fulfillment/returns-apps/manage-reverse-fulfillment-orders) with the GraphQL Admin API.
- Learn how to [manage reverse deliveries](/docs/apps/build/orders-fulfillment/returns-apps/manage-reverse-deliveries) with the GraphQL Admin API.