Bugs in Shopify's Returns Admin and Webhook

Seems to be at least one if not two bugs in the returns system when refunding/restocking multiple units of the same product variant / line item, when processing refunds for different units independently and selecting different restock options.

A) Choosing to restock one unit, then choosing not to restock another unit in a separate refund, results in being able to restock all units at a later time (duplicating the restock for any previously restocked units).

B) The shopify/returns/create webhook contains incorrect restock and restock_type values, seemingly using the values for the previous line item refund and not the current one. (TBF I’m getting the webhooks through an app which might be the source of the issue, so interesting to see if others can replicate).

To replicate either, follow the below:

Purchase 3 x same variant

  • product page stock correct, was 5 avail, now 2 avail, 3 com

Fulfil all 3

  • stock correct, 2 avail

Initiate return for 2 of 3.

Process Return for 1/2, select Restock

  • stock correct, 3 avail
  • shopify/refunds/create webhook correct (restock = true, refund line items: qty = 1, restock type = return).
  • order page correctly shows 1/2 returned.

Process Return again, for 1/1 but DON’T select restock.

  • stock correct, 3 avail
  • webhook now incorrect; same as initial return (restock = true, refund line items: qty = 1, restock type = return).

Click Restock, select 2 of 2.

  • Incorrectly allows restock of 2 units, despite 1 already having been restocked.
  • stock incorrect, 5 avail (should be 4)

Restock fulfilled item, for 1/1 and select Restock

  • webhook incorrect; uses the webhook that should have been present in previous return (restock = false, refund line items: qty = 1, restock type = no_restock).
  • stock correct, 5 avail (likely will be incorrect after further items are refunded/restocked)

EDIT: After a bit more testing, seems the webhook issue is that after refunding a line item unit with a restock, any future refunds for the same line item will also show as a restock (restock = true and restock_type = return) whether or not the restock option is chosen with them.
If a non-restock refund is done first, this isn’t an issue, until a restock refund is done.
Also doesn’t affect anything other than the webhook as far as i see (stock counts don’t change incorrectly in admin).

EDIT 2: narrowed the webhook issue down to the API restock and restockType values being unique to a RefundLineItem, but NOT to a unit within that, and once set to REFUND / restock=true, will not set back to NO_RESTOCK.

Which means any webhooks or future queries to the line item within a refund, once one of the units has been restocked, will not differenciate between restocked and non restocked units even when querying the unique RefundLineItem object (they’re all show as restocked if one of them has been).

So… that’s probably as designed, and would need SF to change or add an additional value in the RefundLineItem object to correctly query units of the same line item for their actual restock status.

Have a feeling the ability to restock more items than you sold is also by design, just dumb.

1 Like

So far most accurate way of dealing with returns I’ve found is this:

  • Subscribe to both shopify/refunds/create and shopify/reverse_fulfillment_orders/dispose.

  • If return=null in shopify/refunds/create, the restock values are accurate.

  • If return !=null, ignore as the restock values are inaccurate (tied to the line item not unit) in preference of…

  • shopify/reverse_fulfillment_orders/dispose will trigger if shopify/refunds/create return != null and there was a restock, giving correct unit qty.

  • shopify/reverse_fulfillment_orders/dispose will not trigger if there wasn’t a restock involved.

Also, never use the inline restock qty in admin (see pic) for previously refunded but not restocked item, as it’s basically just a shortcut to available inventory and doesn’t trigger any webhooks to suggest it’s a restock of a returned item (and it lets you restock more units than exist).

And if the order’s only partially fulfilled when any of this happens, afaict it all goes fubar.

Hey @pepsi_max2k, thanks for the reports here. It looks like you have been able to resolve most of the issues here. To make sure I’m not missing anything, can you clarify what issues are still remaining and steps I can take to replicate?

Have you looked in to the new return processing options? This release has cleared up some of the frustrations with the returns process.

Thanks @KyleG-Shopify - unfortunately it’s still acting odd despite CS’s insistence they fixed it.

The refunds/create webhook still contains restock=true regardless of whether an individual refund contained a restock (don’t know if this is buggy or by design as linked to the one line item, but you’d assume it could provide the correct restock value if it includes the correct unit count).

Also yes I’m trying via the reverse_fulfillment_orders/dispose webhook but this is also (possibly) buggy and doesn’t trigger consistently. Usually only if there’s a change of units being restocked - if you restock 1, don’t restock the next, restock the next, it’ll only trigger on the first and not the 1st and 3rd as I’d expect. Maybe it’s tied to another line-item-only type thing idk.

So yeah I’ve no idea how to consistently get correct restock data via webhooks.

To replicate, do as above screenshots on any item, or simpler: Just buy multiple units of the same variant (eg. 10), initiate a return, then start refunding one by one, alternating between not restock and restock. You’ll see the refunds/create webhook get stuck on restock=true after the first restock (possibly resets if you start refunding different qty of units at once). And dispose webhook fires whenever it wants, not whenever there’s a restock (although it’s never fired when there’s been no restock, thankfully).

EDIT:

Ok seems the restock data in the refunds webhook is a known issue due to semi-deprication.
See Is restock_type field reliable for handling refunds? - #3 by arsuceno - Shopify Community CS “This is why you are getting [incorrect restock value] now, as restocks done on Admin are no longer done under a refund mutation, but instead under a reverseFulfillmentOrderDispose mutation.
And Shopify Native Exchanges “Restocking through the Return APIs means means moving away from restocking though the Refund API and will result in static restock values within the refund object of an order” (no source)

So guessing as soon as you restock it starts using the return api and the restock data gets messed up?

Which would be fine if the dispose webhook triggered on every disposal, but it doesn’t (buggy?), and seems no way to query a specific disposal from any of the refund / returns webhooks that do.

Thank you. I think I was able to replicate this.

First issue, I noticed is that if I have multiple restock types in a single return, that all of the refund create webhooks return as restock true, even on the ones where restock was not selected.

Second issue, I only received a single dispose webhook per return, when I had multiple dispositions on that return.

Does that summarize what you are seeing or am I missing anything?

That seems about it - seems to vary slightly on the combination of returns, fulfilment and restocks but testing it all just got confusing. Assuming all stems from the same bug/design.

Also the issue of being able to restock more than you sold through admin, you can still restock units tha have essentially been restocked already, but they may well be by design somehow. But that’s a minor issue (no different from someone manual adjusting available stock really).

Thanks for confirming that. I’ll let you know what I find out.

1 Like

Hey Christopher,

Closing the loop here, we have created an internal issue to look in to why this is happening. I don’t have a timeline on a fix at this point, but I’ll keep an eye on it and update here when there’s movement.

Thanks again for reporting that and the great details you’ve shared.