Refunding an unfulfilled item without restocking

Hi, is there any way to refund an unfulfilled item without restocking it, currently it can only be refunded with restocking like this with refundCreate - GraphQL Admin.

        "input": {
          "orderId": "gid://shopify/Order/6661365137722",
          "allowOverRefunding": false,
          "refundLineItems": [
            {
              "lineItemId": "gid://shopify/LineItem/16239735832890",
              "locationId": "gid://shopify/Location/100670144826",
              "quantity": 1,
              "restockType": "CANCEL",
            }
          ],
          "notify": false,
          "transactions": []
        }

When it is done through shopify admin instead of API, it uses a different graphql api with the extra field "removal": true together with "restockType": "NO_RESTOCK" to accomplish this:

{
  "input": {
    "currency": "USD",
    "allowOverRefunding": false,
    "orderId": "gid://shopify/Order/6661357994298",
    "refundDuties": [],
    "refundAdditionalFees": [],
    "refundLineItems": [
      {
        "lineItemId": "gid://shopify/LineItem/16239721349434",
        "quantity": 1,
        "restockType": "NO_RESTOCK",
        "removal": true
      }
    ],
    "refundImportTaxes": null,
    "refundMethods": [],
    "shipping": {
      "amount": "0.0"
    },
    "notify": false,
    "note": "",
    "transactions": [],
    "idempotencyKey": "ebb622cf-2ae2-4dee-8c3b-c67cb4e7e501",
    "adjustOrderBalanceForPartialRefund": false
  }
}

however, the “removal”: true field is not available on the public shopify refundCreate API under any version, it’ll be very helpful if that field is made available because for our fulfillment workflow, those items should not be restocked because the inventory is no longer there.

Hey @Andrew_Jaanuu, have you tried to use the NO_RESTOCK value of restockType?

1 Like

It will end up refunding the shipped quantities first instead of the unfulfilled quantities first when the line item is partially fulfilled, which is not an option

Hey @Andrew_Jaanuu, have you looked in to our new return processing API’s?

Sorry my use case is for cancelling unfulfilled items by refunding them, not doing a return.

The reason I suggest processing these using the returns workflows is it will give you more control over the disposition (not restocked)

Although issuing refunds to the original payment method on a return will continue to work with returnRefund or refundCreate, returnRefund will be a legacy API, and using refundCreate for returns causes undesired effects for certain cases (example: risk of refunding the wrong item when there are multiple quantities of the same item on an order). The best practice is to integrate with returnProcess for this use case as well.

Return is meant for line items quantities already fulfilled, and my use case is to refund unfulfilled items, in which returnRefund is not the right API.

Thanks for that, Andrew.

I was getting hung up on this point and forgetting about the unfulfilled part. I should have tested first. :upside_down_face:

The best practice is to integrate with returnProcess for this use case as well.

I did some further testing with other mutations. What works best in this case looks to be editing the order to remove the unfulfilled line items and select to not restock. From there, issuing a manual refund for the amount of the removed items.

One little quirk I noticed with this though is when you specify the quantity, this is the total of unfulfilled items you want on the order. In this example, the order had 1 fulfilled and 1 unfulfilled, so I set this at 0 to remove the unfulfilled item.

mutation OrderEditSetQuantity {
    orderEditSetQuantity(
        id: "gid://shopify/CalculatedOrder/127080169494"
        restock: false
        quantity: 0
        lineItemId: "gid://shopify/CalculatedLineItem/44117372010518"
    ) {
        calculatedOrder {
            id
            lineItems(first: 5) {
                edges {
                    node {
                        id
                        quantity
                    }
                }
            }
        }
        userErrors {
            field
            message
        }
    }
}

This is not the right solution because it changes the original order making it look fully fulfilled instead of partially fulfilled. I gave up this and just chose to do refundCreate with restocking instead to keep things consistent:

{
        "input": {
          "orderId": "gid://shopify/Order/6661365137722",
          "allowOverRefunding": false,
          "refundLineItems": [
            {
              "lineItemId": "gid://shopify/LineItem/16239735832890",
              "locationId": "gid://shopify/Location/100670144826",
              "quantity": 1,
              "restockType": "CANCEL",
            }
          ],
          "notify": false,
          "transactions": []
        }
}

My use case requires refunding the item without actual dollar amount refund while keeping the original quantity, which is common for reporting purpose to keep the order consistent after fulfillment and this is not possible with orderEditSetQuantity.

This does seem to be the best option after going through these other workarounds. Thanks for taking the time to clarify. This will be useful to other developers who may run in to a similar limitation.

After this, are you then adjusting the inventory after the refund when it’s not restocked?

Yes, I need to manually adjust the inventory after refund while taking the risk of overselling before the inventory gets adjusted. Ideally Shopify should add an extra option for refunding unfulfilled line items without restocking.

I agree, having an additional option like cancel-norestock or similar would be what’s needed.

Would it work to move an existing item to safety-stock or similar first and then refund to prevent the overselling?

Can you share a little more context on your specific use case so I can better explain this limitation to our product teams?

The context on my specific use case is to close the old partially fulfilled orders without restocking where the unfulfilled quantities are no longer in stock, it can be done on Shopify admin dashboard while not through API, which prevents automation because it needs to be done manually on each order one by one. The API should be able to do the same thing like what’s possible on the admin dashboard.

1 Like

Hey Andrew!

Following up here to let you know we have looked further in to this and are looking at ways to clear up this inconsistency between the admin and the API.