Migrating order and purchase history

Of everything in a shop migration, the order history gets the least attention and deserves the most, because it is the one dataset you cannot rebuild from a supplier feed or anywhere else. In this article I set out plainly what moves when I bring years of orders into a custom Solidus store, why imported orders are a faithful read only record rather than live orders you can run again, and the awkward edges that catch people out. Then, using an invented Leeds homeware shop moving off WooCommerce, I show how you reconcile a hundred thousand orders to the penny. The point I keep coming back to is that the history is not a cost to carry but the fuel for every forecast and every piece of customer analysis the new shop can do.

Years of orders are not a detail you leave behind

When a shop moves off a rented platform, the catalogue and the customer list get all the attention, and the order history gets treated as something you can tidy up later. That is backwards. The catalogue you can rebuild from a supplier feed if you have to. The order history you cannot rebuild from anything, because it is the record of what actually happened: who bought what, at which price, on which day, with which tax, shipped where, refunded or not. Lose it and you have thrown away both your legal record and the single most valuable dataset the business owns.

This is the honest guide to what happens to that history when I move a shop to a custom store built on Solidus, the open source Rails commerce framework I build on. I will be plain about what comes across cleanly, what comes across as a read only record and nothing more, and the awkward edges that catch people out. Then I will make the case that the history is not a cost to carry but the fuel for everything useful you can do on the new store: demand forecasting, reordering, cohort analysis and basket analysis. This piece is one spoke of a wider series, so start with the parent, what moves and what does not when you migrate an online shop, and read this alongside its sister piece on analytics and historical data for forecasting.

Why you keep it, and why losing it is not an option

There are five reasons an established shop must carry its order history across, and they stack.

The first is customer service. A customer emails about a parcel that never arrived, or a warranty claim on a chair bought two years ago. Your staff need to open that order, see the line items, the price paid, the delivery address and the tracking, and answer in one reply rather than ten.

The second is the law. Tax authorities set minimum periods for keeping business and tax records, and an order is a tax record. In the United Kingdom a limited company must keep its accounting records for six years from the end of the last financial year they relate to, and longer if a transaction spans more than one accounting period or a compliance check is open.1 The periods differ by country, and a shop that sells across borders answers to more than one of them at once. Here is the picture for the jurisdictions this series covers.

Where you keep tax recordsMinimum retentionSource
United Kingdom (company accounting records)6 years from the end of the last financial yearHMRC 1
Ireland (VAT and business records)6 years, unless Revenue agrees a shorter periodRevenue 2
Germany (books, annual accounts)10 yearsAbgabenordnung §147 3
Germany (accounting vouchers, invoices)8 years, reduced from 10 in 2025Abgabenordnung §147 3
Austria (books, records and vouchers)7 years from the end of the calendar yearBundesabgabenordnung §132 4

The third reason is warranty and returns. A guarantee runs from the date of sale, and a return needs the original order to check what was bought and what was paid. The fourth is money: repeat purchase rate, average order value and customer lifetime value all read straight off the order history, and they are how you know which customers and which products are worth keeping. The fifth is forecasting, which I come back to at length, because it is where the history pays you back.

Notice that the first four are reasons you must not lose the data. The fifth is a reason you should be glad to own it.

What actually moves

An order is not a single thing. It is a small bundle of records, and each part has to come across for the order to be worth anything. These move cleanly, with mapping work.

  • The order itself: its number, its date and time, its status (placed, paid, shipped, completed, cancelled), and its currency.
  • The line items: for each one the product and variant, the quantity, and the price at the time of sale, which is almost never today's price.
  • The money: the tax charged, any discount or promotion applied, the shipping charge and the order total, exactly as the customer was billed.
  • The people and places: the link to the customer account, and the billing and shipping addresses as they were captured on the day, not as the customer's address book reads now.
  • The fulfilment: which items shipped, when, by which carrier, and the tracking reference.
  • The aftermath: refunds, partial refunds and returns against the order, with their amounts and dates.

Getting this out of the old platform is usually a question of either a report or an interface. Most platforms give you a full order export as a spreadsheet: Shopify, for instance, exports a comma separated file covering line items, financial and fulfilment status, totals, discounts, shipping method, dates and addresses, delivered as a download for small sets and by email for anything over fifty orders or any export by date.5 For a clean, repeatable pull I prefer the platform's interface where it has one. WooCommerce exposes every order through its REST interface at the orders endpoint, so a script can page through the lot, fields intact, and write them straight into the shape the new store needs.6 A report is fine for a one off. An interface is better when you will run the extract several times, which, as you will see, you always do.

Prices and taxes must be kept as they were

Here is the rule that decides how imported orders are stored, and it is the part most migration plans get wrong. An order records what was true on the day it was placed. The price was whatever the price was then. The tax was whatever the rate was then. The discount was whatever ran that week. None of it may be recalculated against today's prices, today's tax rates or today's promotions, because then the order would no longer match the invoice the customer holds, the payment that was taken or the figure your accountant already filed.

Tax rates are the clearest example, because they change and the changes are dated. The United Kingdom standard VAT rate rose to 20% on 4 January 2011, from 17.5%.7 An order from December 2010 carries 17.5% forever. If a migration recomputed its tax at 20%, the order would overstate what was charged, and every total that depends on it would be wrong. The same holds for a shop that ran a sale, honoured a voucher, or sold in a second currency: the recorded figures are the historical truth and must be imported as fixed numbers, not as formulas the new store evaluates.

This is why imported orders are stored as historical records rather than fed back through the machinery that prices a new basket. Which leads straight to the next point.

Imported orders are read only by design

On a modern commerce platform a live order is not a static row. It is a small state machine: a basket becomes an order, an order moves through address, delivery, payment and confirmation, and only then is it complete. Solidus works exactly this way, with an order advancing through those states and carrying a completion timestamp once it is done.8 Each transition fires the right tax calculation, the right promotion logic and the right stock movement for a shop running today.

An order from your old shop already went through all of that, years ago, in a different system, under different prices and rules. You cannot feed it back through the new store's live engine, because the engine would try to price it, tax it and promote it as if it were happening now, and get a different, wrong answer. So imported orders are brought in as completed historical records: faithful copies, locked, there to be looked up and analysed, never reprocessed. New orders, placed after cutover, use the live engine as normal.

In practice this means the new store holds two kinds of order that look similar in a list but behave differently. A historical order you can read, search, report on and show the customer in their account. A live order you can also act on: refund it, reship it, edit it. Trying to make imported orders fully live again is a tempting mistake, and it is the wrong one. The honest design keeps them as the record they are.

The awkward edges

If migrating order history were only a matter of copying clean, completed sales, it would be a weekend of work. It is not, because of the edges. These are the cases to plan for by name.

Partial refunds and partial returns. An order of four items where one came back and was refunded is not fully refunded and not untouched. The import has to carry the exact refunded amount and the exact lines it applied to, or your revenue by month will not reconcile.

Exchanges and replacements. A returned item swapped for another sometimes lives as a refund plus a new order, sometimes as an edit to the original. Decide which, and apply it consistently, or the same event will be counted twice in one shop and not at all in the other.

Split shipments. One order delivered in two parcels on two dates, perhaps from two locations, has more than one fulfilment record. Flatten it to a single shipped date and you lose the truth about delivery times, which is exactly the data you later want for service level analysis.

Multi currency orders. A shop that sold in pounds and euros recorded each order in the currency the customer paid. Those figures stay in their original currency, with the exchange basis recorded, and are only ever converted for reporting, never rewritten.

Tax that changed over the years. The VAT example above is not a footnote. A shop with a decade of history has orders at more than one rate, and the import must preserve the rate each order actually carried.

Gift cards and store credit. An old order part paid with a gift card or store credit needs the tender recorded as it was, otherwise the cash it actually took will not match the bank.

Orders in flight at cutover. The hardest edge is the order that is placed but not yet shipped, or shipped but not yet delivered, on the day you switch. The honest answer is not to migrate these as live orders into the new store. Let the old system finish them: it already holds the payment, the stock reservation and the customer's expectation. Start the new store clean, with a known cutoff, and import those last orders as history only once they have completed on the old system. A clean line beats a clever one.

What the history is worth

Now the part that turns a cost into an asset. Everything above is about carrying the record faithfully. This is about what the record lets you do once it is yours, in your own database, queryable, rather than locked inside a platform that rents it back to you through a reporting screen. Owning the data is the whole point, and it is the theme of who actually owns your business data.

Order line history is the minimum raw material for demand forecasting. A forecast needs to see each product's sales over time to pick up three things: the trend (is demand drifting up or down), the seasonality (the Christmas peak, the January lull, the summer dip) and the autocorrelation (this week's sales carrying information about next week's). Those are the standard components a time series is decomposed into, and seasonality and short term dependence are read directly from the pattern of past sales.910 I go through the mechanics in forecasting demand, autocorrelation and seasonality, and the honest question of how much you need in how much data do you actually need. The short version: a forecast is only as good as the clean history behind it, and two or three years of orders, reconciled and correct, is what separates a usable forecast from a guess. The wider case for forecasting on a shop you own is in AI powered demand forecasting for ecommerce.

The same history feeds three more things that a rented reporting screen rarely gives you. Safety stock and reorder points, so you hold enough to meet demand through the resupply gap without drowning in stock, which needs the variability of past demand, not just its average. Cohort and repeat purchase analysis, so you know whether customers who arrived in a given month keep coming back, and what a customer is worth over time. And basket analysis, which pairs reliably sell together, so the shop can suggest the right companion product, a subject I treat in cross sell and upsell at checkout. None of this is possible if the history was left behind, and all of it is routine once the history sits in a database you control.

So the honest framing is this: you keep the order history because the law and your customers require it, and you are glad you kept it because it is the input to every piece of analysis that makes the new shop smarter than the old one.

The practical path

Moving the history is a sequence, and the order matters.

First, extract. Pull the full order history from the old platform, by interface where there is one, by report where there is not, with every field listed above. Expect to run the extract more than once, because the first pass always reveals a field you missed.

Second, map. The old platform's product identifiers, status names, tax labels and tender types have to map to the new store's. An old order points at a product that may have a new identifier, or no longer exists and needs a placeholder so the line still reads. This is careful, unglamorous work and it is where the days go.

Third, import as historical orders. Load the mapped orders into the new store as completed records, not through the live checkout, preserving every figure as captured.

Fourth, reconcile. This is the step people skip and regret. Count the orders by month and sum the revenue by month on the old system, then on the new one, and make the two match exactly. Not roughly. A single order miscounted is a thread you pull until the whole month unravels. The monthly order count and the monthly revenue, old against new, to the penny, is the acceptance test.

Fifth, verify a sample by hand. Pick a dozen orders across the range, including a partial refund, a multi line order, a discounted order and one from before a tax change, and check each field against the old shop's screen. Automated totals can match while individual fields are quietly wrong, and only a human eye catches that.

A worked example

Everything below is invented to show the steps. Calder and Rowe is a homeware shop in Leeds, trading at calderandrowe.example, run by Priya. It has been on WooCommerce for five years and has outgrown it: the reporting cannot answer her questions and the checkout cannot do what she wants. She is moving to a custom Solidus store she will own. The history to bring is about 120,000 orders across those five years, a little over 11 million pounds of revenue.

I pull the orders through the WooCommerce REST interface rather than a spreadsheet, because 120,000 orders will need several passes and a script is repeatable where a manual export is not.6 The first pass surfaces the usual problems: a run of 2010 era orders at 17.5% VAT sitting next to recent ones at 20%, which the import must keep apart;7 about 900 orders part paid with store credit; a spell two winters ago when a bundle promotion means the line prices do not sum to the order total unless the discount line is carried across; and roughly 300 orders split across two shipments.

Mapping takes the bulk of a week. Priya's product codes changed once in the five years, so some old lines point at codes that need translating, and about forty discontinued products become placeholders that still show the name and price the customer paid. Then the import loads everything as historical, completed orders into Solidus.

Reconciliation is where the project is really tested. The first run is out by 3,214 pounds across sixty months. Tracking it down finds two causes: the store credit tenders were being dropped, and a leap day order had fallen through a date filter. Fixed, the second run matches: every month's order count identical, every month's revenue identical to the penny, old system against new. That reconciliation report, signed off, is the moment the history is trustworthy.

The payoff comes a fortnight later. For the first time Priya can run a clean seasonality view across all five years in her own database: a reliable November and December peak, a deep January trough, a smaller late summer rise she had always half sensed but never measured. On WooCommerce that query was slow, partial and locked behind the reporting screen. On a store she owns it is a question she can ask any time, and the answer is the starting point for next year's buying. The history she was tempted to leave behind turned out to be the most useful thing she brought.

What this comes down to

Order history moves, but it moves as a faithful, read only record, reconciled to the penny, not as live orders you can run again. The awkward edges, partial refunds, split shipments, changed tax rates, store credit and the orders in flight on cutover day, are each handled on purpose, not glossed over, and the orders still open when you switch are finished on the old system so the new one starts clean. Do that properly and you have met the law and kept your customers served. The real reward comes after: the history, now in a store you own and can query, is the raw material for forecasting, reordering and the customer analysis the old platform never let you do. That is the difference between renting your past and owning it.

If you are weighing a move and worry about years of orders, bring it to a free workshop and I will map exactly what your history contains, what will move cleanly, what needs a decision, and what it is worth once it is yours. The first two weeks of work are on me, and if the reconciliation looks hard I will tell you so before we start.

Footnotes

  1. HM Revenue and Customs, Running a limited company: company and accounting records (keep records for six years from the end of the last financial year), GOV.UK, 2026, https://www.gov.uk/running-a-limited-company/company-and-accounting-records ↩ ↩2

  2. Irish Revenue, How long do you keep records for? (six years unless Revenue gives written permission for a shorter period), revenue.ie, 2026, https://revenue.ie/en/vat/vat-records-invoices-credit-notes/vat-records-to-be-kept/how-long-keep-records.aspx ↩

  3. Abgabenordnung §147, Ordnungsvorschriften für die Aufbewahrung von Unterlagen (ten years for books and annual accounts, eight years for accounting vouchers), Bundesministerium der Justiz, gesetze-im-internet.de, 2026, https://www.gesetze-im-internet.de/ao_1977/__147.html ↩ ↩2

  4. Bundesabgabenordnung §132, Aufbewahrung von Büchern, Aufzeichnungen und Belegen (seven years), jusline.at, 2026, https://www.jusline.at/gesetz/bao/paragraf/132 ↩

  5. Shopify, Exporting orders to a CSV file (contents of the order export and the volume rules), Shopify Help Center, 2026, https://help.shopify.com/en/manual/orders/export-orders ↩

  6. WooCommerce, REST API Documentation: Orders (list, retrieve and page through orders programmatically), woocommerce.github.io, 2026, https://woocommerce.github.io/woocommerce-rest-api-docs/#orders ↩ ↩2

  7. HM Revenue and Customs, VAT rates (standard rate 20%, raised on 4 January 2011 from 17.5%), GOV.UK, 2026, https://www.gov.uk/vat-rates ↩ ↩2

  8. Solidus, core/app/models/spree/order.rb (the order state machine: cart, address, delivery, payment, confirm, complete, with a completion timestamp), solidusio/solidus on GitHub, 2026, https://github.com/solidusio/solidus/blob/main/core/app/models/spree/order.rb ↩

  9. Rob J Hyndman and George Athanasopoulos, Forecasting: Principles and Practice, 3rd edition, chapter on time series decomposition (trend, seasonal and remainder components), OTexts, 2021, https://otexts.com/fpp3/decomposition.html ↩

  10. Rob J Hyndman and George Athanasopoulos, Forecasting: Principles and Practice, 3rd edition, autocorrelation (seasonality and short term dependence in the autocorrelation function), OTexts, 2021, https://otexts.com/fpp3/acf.html ↩

Worried about what happens to years of orders if you move? Bring it to a free workshop and we will map exactly what your history holds, what moves cleanly, what needs a decision, and what it is worth once it is yours. The first two weeks of work are on me.

1%of every invoice goes to a UK charity you pick.

A donation, never sponsorship. You choose the cause at onboarding.

The story behind the pledge →

Stay ahead of your competition.

The latest innovative products and services, straight to your inbox before your competitors hear about them.

Get up to 5% off your first six months: 1% per topic you pick, the full 5% when you take everything. Limited offer · ends 31 December 2026.

New clients only. Terms apply.

* Up to 5% off your first six monthly invoices, new clients only. Full terms.

Questions about pricing, contracts or how we work together?

Read the FAQ