Home>Migrations & Replatforming>Data & Customer Migration>Do RMA Records Migrate to Shopify Returns?

Do return/RMA records and their approval history migrate cleanly to Shopify's returns model or a returns app like Loop/AfterShip?

Return records do not migrate. Shopify's returnCreate mutation requires at least one fulfilled line item that has not yet been refunded, and the Return object exposes no field for backdating a request or importing prior approval history (per shopify.dev, September 2026). Historical RMAs land as order notes or a read-only archive, not as returns.

The blocking constraint, stated precisely

Shopify's returns model is built for returns you are about to process, not returns you already processed. Two documented facts close the door on importing history:

  • returnCreate "requires at least one fulfilled line item that hasn't yet been refunded" (per shopify.dev, September 2026). A closed RMA is, by definition, already refunded. The mutation will not accept it.
  • The Return object carries createdAt, requestApprovedAt and closedAt, but the mutations that create and approve returns take no timestamp arguments (per shopify.dev, September 2026). Even a return you could create would be stamped today.

There is one useful exception in the docs worth knowing: "If you create a return on an archived order, then the order is automatically unarchived" (per shopify.dev, September 2026). That matters for open RMAs, not closed ones.

So what do you actually do with the history

Category of RMAWhere it goesWhy
Closed, refunded, resolvedRead-only archive outside Shopify, plus a summary tag or note on the migrated orderCannot be expressed as a Shopify return at all
Open, item not yet receivedRecreate by hand in the returns app after cutover, as a new returnSmall volume, and the customer-facing state has to be right
Open, item received but not refundedRefund at the old processor if its window allows, then record the refund on the migrated orderAvoids a return object that would try to restock into the wrong location
Warranty claims with a long tailArchive plus a customer metafield flagging the entitlementWarranty periods outlive the migration and nothing in Shopify models them

Do Loop or AfterShip fix this

No, and for the same reason. Both are live and both are real options for returns going forward. Loop Returns & Exchanges lists a free Core tier, Essential at $155 per month and Advanced at $340 per month (verified on both apps.shopify.com and loopreturns.com, September 2026). AfterShip Returns & Exchanges is rated 4.7 stars across about 1,540 reviews, with a free tier, Essentials at $19 per month including 20 returns, and Premium at $119 per month including 100 returns (verified on the app listing and the AfterShip partner page, September 2026).

What neither does is invent an import path Shopify does not expose. A returns app builds its return objects on top of Shopify's orders and fulfillments. It inherits the same constraint: no fulfilled, unrefunded line item means no return to attach to.

The thing teams get wrong: approval history is a compliance artifact, not a data model

Approval history usually matters for one of three reasons, and only one of them needs the data to be inside Shopify.

  • Customer service context. Solved by an order note or a tag. An agent needs to know a return happened and why, not to replay the approval workflow.
  • Vendor chargeback and supplier recovery. Solved by the archive. The counterparty is the supplier, not Shopify.
  • Regulatory or contractual retention. Solved by keeping the old records, in the old format, for the required period. Re-expressing them inside a new system is the version that fails an audit, because the re-expression is not the original record.

When NOT to try

  • When an integrator promises to import returns. Ask which mutation. If the answer is a custom metaobject, you are paying to build an archive inside Shopify that no Shopify screen will render.
  • When your return rate is high and the history is large. The archive gets better as the volume grows, not worse.
  • When open RMAs number in the hundreds at cutover. Freeze new return requests for a short window instead, clear the backlog on the old platform, and migrate with an empty queue.

The Deploi point of view

Our own position, from building on Shopify. Separate from the facts above.

  • Our take: Plan the returns cutover as a queue-drain, not a data migration. We scope it as three dates: last day a return can be requested on the old platform, last day it can be received there, and the day the new returns app goes live. Anything still open on the third date is recreated by hand and counted, because the count is small and the alternative is a build with no supported path.
  • Where we disagree: Migration vendors list returns alongside orders and customers as a migratable object class. It is not one. Orders have an import API and returns do not, and quoting them in the same breath is how a fixed-price migration acquires an unpriced surprise in week six.
  • What this page adds: that the blocker is a specific documented precondition on returnCreate plus the absence of any timestamp argument, which is why no app, including Loop and AfterShip, can offer an import path.

Reviewed by Martin Dejnicki, Director of SEO & AI Search. Facts verified 2026-09-14.