A return represents the intent of a buyer to ship one or more items from an order back to a merchant or a third-party fulfillment location. Merchants can manage their returns in Shopify, and returns apps can take actions on behalf of merchants.
This guide shows you how to manage returns 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
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-4-optional-create-a-return) in the next step.
> 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
> Note:
> You can skip this step if you've already [requested a return](#step-3-request-a-return) or [created a return](#step-4-optional-create-a-return)
You can use the [`returnCalculate`](/docs/api/admin-graphql/latest/queries/returnCalculate) query to calculate financial data for a return with given inputs. Note that this does not create the return, it simply calculates the financial impact of a return if created with the same inputs.
## Step 3: Request a return
You can use the [`returnRequest`](/docs/api/admin-graphql/latest/mutations/returnRequest) mutation to create a return with its status set to `REQUESTED`. This mutation should be used to create returns that need to be approved by the merchant. 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.
To request a return, provide the ID of the order and the return line items as input to the mutation. The response returns the return ID and the [return's status](/docs/apps/build/orders-fulfillment/returns-apps#return-statuses).
> Note:
> You can't [cancel](#step-7-optional-cancel-a-return) a requested return. Instead, you need to [approve](#approve-a-request) or [decline](#decline-a-request) the request.
### Approve a request
You can use the [`returnApproveRequest`](/docs/api/admin-graphql/latest/mutations/returnApproveRequest) mutation to approve a single requested return. This changes the [return's status](/docs/apps/build/orders-fulfillment/returns-apps#return-statuses) from `REQUESTED` to `OPEN`. Approving the return 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.
To approve a request, provide the ID of the return to be approved. The response returns the return ID and the return's status.
> Caution:
> Approving a return is a permanent action. After a return is approved, you can't change its status to `REQUESTED` or `DECLINED`.
### Decline a request
You can use the [`returnDeclineRequest`](/docs/api/admin-graphql/latest/mutations/returnDeclineRequest) mutation to decline a single requested return. This changes the [return's status](/docs/apps/build/orders-fulfillment/returns-apps#return-statuses) from `REQUESTED` to `DECLINED`. A declined return doesn't have [reverse fulfillment orders](/docs/apps/build/orders-fulfillment/returns-apps/manage-reverse-fulfillment-orders). As a result, shipping can't be added to the declined return.
You can only decline a return if the return meets the following criteria:
- It must be in a `REQUESTED` state.
- It can't have been refunded.
To decline a request, provide the ID of the return to be declined. The response returns the return ID and the return's status.
> Caution:
> Declining a return is a permanent action. After a return is declined, you can't change its status to `REQUESTED` or `APPROVED`.
## Step 4 (Optional): Create a return
> Note:
> You can skip this step if you've already [requested a return](#step-3-request-a-return).
If your workflow involves approving or declining requested returns outside of the Shopify platform, then you should create a return using the [`returnCreate`](/docs/api/admin-graphql/latest/mutations/returnCreate) mutation.
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` mutation does the following:
- It 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](#approve-a-request).
- It 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.
- It creates a sales agreement with a `RETURN` reason, which links to all sales created for the return/exchange
- It creates sales records that reverse the sales records for the items being returned
- It creates sales records for any exchange line items
The created return is marked as **Return in progress** in the order details view in the Shopify admin:
When a return is created with exchange items, those 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 see [manage fulfillments](/docs/apps/build/orders-fulfillment/fulfillment-service-apps/build-for-fulfillment-services).
## Step 5: Retrieve a return
After you've created a return, you can use the [`return`](/docs/api/admin-graphql/latest/queries/return) query to retrieve the return by its ID. The response returns the order ID associated with the return and the [return's status](/docs/apps/build/orders-fulfillment/returns-apps#return-statuses).
## Step 6 (Optional): Remove return line items from the return
If a customer changes their mind about returning an item, you can remove that item from the return. Removing a return line item will revert that order line item back to being fulfilled and may change the order balance. If you remove the only return line item in the return, the return status will automatically change to `CLOSED`.
## Step 7 (Optional): Cancel a return
If you create a return by mistake, have an error in the created return, or a customer has changed their mind about wanting to return an item, then you can cancel the return that you've created. Canceling a return restores an order's line items back to being fulfilled. To cancel a return, provide the ID of the return as input to the [`returnCancel`](/docs/api/admin-graphql/latest/mutations/returnCancel) mutation.
You can only cancel a return if the return meets the following criteria:
- It must be in an `OPEN` state.
- It can't have cancelled fulfillments.
- It can't have been refunded.
- It can't have dispositions.
- It can't have Shopify Shipping return label. Returns with manually-uploaded return labels and manually-provided tracking information (not PDFs) can be canceled.
Returns to Shopify Fulfillment Network (SFN) might be cancelable. If SFN rejects the cancelation request, then a "return failed" description displays in the Shopify admin.
When cancelling a return, you can expect that all sales records generated from the creation of a return will be reversed, nullifying the financial impact of the return on the order.
Note: This will not affect the sales generated for exchange line items, nor will it cancel the fulfillments for any exchange line items.
Canceling a return removes it from the order details view in the Shopify admin:
## Step 8: Query a suggested refund
A [suggested refund](/docs/api/admin-graphql/latest/objects/SuggestedReturnRefund) represents a refund that Shopify suggests based on the items being reimbursed. In your query, provide the ID of the return, the ID of the return line item, and the quantity of the line item.
## Step 9: Issue a refund
When you refund an order, you send payment back to the customer. Using the [`returnRefund`](/docs/api/admin-graphql/latest/mutations/returnRefund) mutation, you can issue a refund and associated it with the related return. You can refund an entire order or only part of an order.
The refunding behavior of this mutation is similar to the [`refundCreate`](/docs/api/admin-graphql/latest/mutations/refundCreate) mutation. The main difference is that the `returnRefund` mutation doesn't involve restocking input.
## Step 10: Dispose items
When a merchant or third-party fulfillment service receives a returned item, they can inspect the product to determine whether it's in sellable condition. For example, the product might be stained or missing components.
For health and safety reasons, some products can only be restocked if they are in unopened or brand new condition. If the products are returned in an opened or used condition, then the products are disposed of during inspection.
Depending on your use case, you can do the following:
- If you require a delivery to dispose items, then refer to [Manage reverse deliveries](/docs/apps/build/orders-fulfillment/returns-apps/manage-reverse-deliveries).
- If you want to dispose items with no deliveries involved, then refer to [Manage reverse fulfillment orders](/docs/apps/build/orders-fulfillment/returns-apps/manage-reverse-fulfillment-orders).
## Step 11: Close a return
You can use the [`returnClose`](/docs/api/admin-graphql/latest/mutations/returnClose) mutation to close a return at any time. For example, you might want to close a return when a refund has been made and items are restocked, or when items have been marked as returned.
A closed return is marked as **Returned** in the Shopify admin:
## Step 12 (Optional): Reopen a return
If you need to reopen a closed return, then you can use the [`returnReopen`](/docs/api/admin-graphql/latest/mutations/returnReopen) mutation. You can reopen a return only if it was closed.
## Webhooks
As of GraphQL Admin API version 2023-01 and higher, your app can subscribe to webhooks for event notifications related to returns, refunds, reverse fulfillment orders, and reverse deliveries. 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](/docs/apps/build/webhooks/subscribe).
> Note:
> Return webhooks are available only in the GraphQL Admin API.
## Next steps
- Learn how to [manage exchanges](/docs/apps/build/orders-fulfillment/returns-apps/manage-exchanges) with the GraphQL Admin API.
- 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.