Skip to main content

Build self-serve returns using the Customer Account API

Using the Customer Account API, third-party (3P) developers can seamlessly build return apps on new customer accounts without needing additional app authorizations. Partners can query existing returns, create new return requests, and customize the experience for customers.

Additionally, these APIs provide Partners with visibility into an order line item's return eligibility, which incorporates Shopify's Return rules for merchants with this feature enabled. Partners can determine which items can be returned and the expected refund amount, as well as why items are not returnable.

This guide shows you how to use the order query to get the information you need regarding returns and how to request returns on behalf of customers using the Customer API.


  • Your app can make authenticated requests to the Customer Account API.
  • Your store has existing orders 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.
  • You're using the 2025-04 version of the Customer API or higher.

Anchor to Step 1: Query for the return eligibility of an orderStep 1: Query for the return eligibility of an order

If an Order doesn't contain any items eligible for return, then the nonReturnableSummary field on the returnInformation will specify the reason for ineligibility. If the order is eligible for return, then this field will be null.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query Order($id: ID!) {
order(id: $id) {
id
returnInformation {
nonReturnableSummary {
nonReturnableReasons
}
}
}
}

GraphQL input

{
"id": "gid://shopify/Order/1"
}

JSON response

{
"data": {
"order": {
"id": "gid://shopify/Order/1",
"returnInformation": {
"nonReturnableReasons": [
"UNFULFILLED"
]
}
}
}
}

Anchor to Step 2: Get the returnable and non-returnable line items of an orderStep 2: Get the returnable and non-returnable line items of an order

You can use the returnInformation field of an Order to get both the returnableLineItems and the nonReturnableLineItems.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL query

query Order($id: ID!, $first: Int!, $after: String) {
order(id: $id) {
returnInformation {
returnableLineItems(first: $first, after: $after) {
edges {
node {
lineItem {
id
presentmentTitle
currentTotalPrice {
amount
currencyCode
}
}
quantity
}
}
pageInfo {
endCursor
hasNextPage
}
}
nonReturnableLineItems(first: $first, after: $after) {
edges {
node {
lineItem {
id
presentmentTitle
currentTotalPrice {
amount
currencyCode
}
}
quantity
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
}
}

GraphQL input

{
"id": "gid://shopify/Order/1",
"first": 250
}

JSON response

{
"data": {
"order": {
"returnInformation": {
"returnableLineItems": {
"edges": [
{
"node": {
"lineItem": {
"id": "gid://shopify/LineItem/1",
"presentmentTitle": "",
"currentTotalPrice": {
"amount": "1.26",
"currencyCode": "CAD"
}
},
"quantity": 1
}
}
],
"pageInfo": {
"endCursor": "1",
"hasNextPage": false
}
},
"nonReturnableLineItems": {
"edges": [
{
"node": {
"lineItem": {
"id": "gid://shopify/LineItem/2",
"presentmentTitle": "",
"currentTotalPrice": {
"amount": "1.0",
"currencyCode": "CAD"
}
},
"quantity": 1
}
}
],
"pageInfo": {
"endCursor": "2",
"hasNextPage": false
}
}
}
}
}
}

Anchor to Step 3: Get the calculated return amountStep 3: Get the calculated return amount

Use the returnCalculate query to calculate financial outcome of a return based on the line items requested for return. It includes a detailed ReturnFinancialSummary that breaks down the restocking and shipping fees, return subtotal, subtotal with cart discounts, total return amount, and total tax, all presented in both customer-facing (presentmentMoney) and internal shop (shopMoney) currency formats. Additionally, the query retrieves detailed information about each return line item, including current total price, quantity, and associated financial details like subtotal and total tax.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

query CalculatedReturn($orderId: ID!, $returnLineItems: [CalculateReturnLineItemInput!]!, $first: Int) {
returnCalculate(input: {orderId: $orderId, returnLineItems: $returnLineItems}) {
financialSummary {
restockingFeeSubtotalSet {
presentmentMoney {
amount
currencyCode
}
shopMoney {
amount
currencyCode
}
}
returnShippingFeeSubtotalSet {
presentmentMoney {
amount
currencyCode
}
shopMoney {
amount
currencyCode
}
}
returnSubtotalSet {
presentmentMoney {
amount
currencyCode
}
shopMoney {
amount
currencyCode
}
}
returnSubtotalWithCartDiscountSet {
presentmentMoney {
amount
currencyCode
}
shopMoney {
amount
currencyCode
}
}
returnTotalSet {
presentmentMoney {
amount
currencyCode
}
shopMoney {
amount
currencyCode
}
}
returnTotalTaxSet {
presentmentMoney {
amount
currencyCode
}
shopMoney {
amount
currencyCode
}
}
}
returnLineItems(first: $first) {
edges {
node {
lineItem {
id
presentmentTitle
currentTotalPrice {
amount
currencyCode
}
}
quantity
subtotalSet {
presentmentMoney {
amount
currencyCode
}
shopMoney {
amount
currencyCode
}
}
totalTaxSet {
presentmentMoney {
amount
currencyCode
}
shopMoney {
amount
currencyCode
}
}
}
}
}
}
}

GraphQL input

{
"orderId": "gid://shopify/Order/1",
"returnLineItems": [
{
"lineItemId": "gid://shopify/LineItem/1",
"quantity": 1
}
],
"first": 250
}

JSON response

{
"data": {
"returnCalculate": {
"financialSummary": {
"restockingFeeSubtotalSet": {
"presentmentMoney": {
"amount": "0.0",
"currencyCode": "CAD"
},
"shopMoney": {
"amount": "0.0",
"currencyCode": "CAD"
}
},
"returnShippingFeeSubtotalSet": {
"presentmentMoney": {
"amount": "0.0",
"currencyCode": "CAD"
},
"shopMoney": {
"amount": "0.0",
"currencyCode": "CAD"
}
},
"returnSubtotalSet": {
"presentmentMoney": {
"amount": "-82.99",
"currencyCode": "CAD"
},
"shopMoney": {
"amount": "-82.99",
"currencyCode": "CAD"
}
},
"returnSubtotalWithCartDiscountSet": {
"presentmentMoney": {
"amount": "-82.99",
"currencyCode": "CAD"
},
"shopMoney": {
"amount": "-82.99",
"currencyCode": "CAD"
}
},
"returnTotalSet": {
"presentmentMoney": {
"amount": "-82.99",
"currencyCode": "CAD"
},
"shopMoney": {
"amount": "-82.99",
"currencyCode": "CAD"
}
},
"returnTotalTaxSet": {
"presentmentMoney": {
"amount": "0.0",
"currencyCode": "CAD"
},
"shopMoney": {
"amount": "0.0",
"currencyCode": "CAD"
}
}
},
"returnLineItems": {
"edges": [
{
"node": {
"lineItem": {
"id": "gid://shopify/LineItem/46",
"presentmentTitle": "Practical Linen Keyboard",
"currentTotalPrice": {
"amount": "331.96",
"currencyCode": "CAD"
}
},
"quantity": 1,
"subtotalSet": {
"presentmentMoney": {
"amount": "-82.99",
"currencyCode": "CAD"
},
"shopMoney": {
"amount": "-82.99",
"currencyCode": "CAD"
}
},
"totalTaxSet": {
"presentmentMoney": {
"amount": "0.0",
"currencyCode": "CAD"
},
"shopMoney": {
"amount": "0.0",
"currencyCode": "CAD"
}
}
}
}
]
}
}
}
}

Anchor to Step 4: Create the return requestStep 4: Create the return request

Use the orderRequestReturn mutation to send a return request to the merchant. As the name implies, this mutation doesn't directly create a return. Instead, it submits a request that the merchant can approve or reject.

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

GraphQL mutation

mutation OrderRequestReturn($id: ID!, $requestedLineItems: [RequestedLineItemInput!]!) {
orderRequestReturn(orderId: $id, requestedLineItems: $requestedLineItems) {
return {
id
}
userErrors {
message
code
}
}
}

GraphQL input

{
"id": "gid://shopify/Order/1",
"requestedLineItems": [
{
"lineItemId": "gid://shopify/LineItem/1",
"quantity": 1,
"returnReason": "SIZE_TOO_SMALL",
"customerNote": null
}
]
}

JSON response

{
"data": {
"orderRequestReturn": {
"return": {
"id": "gid://shopify/Return/1"
},
"userErrors": []
}
}
}

Using the GraphQL Admin API, you can lean how to do the following:


Was this page helpful?