Platform Documentation

Implementation Guide

Complete technical reference for Shopify sales history migration, security protocols, and data management.

SOP: Historical Sales Data Migration to Shopify

Follow this structured guide to securely migrate historical sales data into Shopify while preserving financial accuracy, customer records, and transaction integrity — without triggering unintended notifications.

This documentation outlines the process for migrating historical sales transactions into Shopify for reporting continuity and operational transparency. It is designed for system administrators and data teams handling large-scale data imports.

Shopify Order Import Guidelines

These rules are based on Shopify Admin API requirements for orderCreate. Following them helps prevent API errors, incorrect reporting, and unwanted customer notifications.

1Disable Automated Notifications for Historical Orders

Shopify may trigger fulfillment or shipping emails if automation is enabled. Ensure notifications are disabled for historical imports to avoid sending outdated emails to customers.

2Set Correct Fulfillment Status

For past or in-person sales, ensure the order is marked as fulfilled. Incorrect fulfillment status may result in invalid shipping workflows or pending fulfillment queues.

3Preserve Financial Accuracy & Reporting Integrity

Always use accurate historical timestamps (processedAt) and correct transaction values to ensure Shopify analytics, taxes, and financial reports remain consistent.

Important: Some behaviors (notifications, fulfillment rules, and reporting) may vary depending on Shopify plan, apps installed, or API configuration.

Phase 1

How to Prepare Your CSV Data File

Before importing, you must format your legacy POS data to match Shopify's strict requirements. Follow these detailed steps to build a perfectly compliant CSV file.

1Download the Template

The easiest way to start is by downloading our pre-formatted CSV template. It contains all the exact column headers you need. Open this in Excel or Google Sheets.

Template

Download the Master CSV

Start your migration with our pre-formatted template. It contains all 61 exact column headers required by the HistoriQ engine to prevent mapping errors.

HistoriQ_Master_Template.csv

61 Columns • UTF-8 Format • Ready to Use

Included Exact Headers

order_numberprocessed_atstatusfulfillment_statusemailshopify_customer_idnotetagsshipping_nameshipping_address1shipping_address2shipping_cityshipping_provinceshipping_province_codeshipping_zipshipping_countryshipping_country_codeshipping_phoneshipping_companybilling_namebilling_address1billing_address2billing_citybilling_provincebilling_province_codebilling_zipbilling_countrybilling_country_codebilling_phonebilling_companyline_item_titlequantitypriceitem_skubarcodediscount_amountdiscount_typediscount_titleline_item_tax_pricetax_titletax_ratetax_pricetax_2_titletax_2_ratetax_2_priceshipping_line_titleshipping_line_priceshipping_line_codeshipping_line_sourcetransaction_kindtransaction_amountcancel_reasoncancel_restockcancel_staff_notecancel_notify_customerfulfillment_tracking_companyfulfillment_tracking_numberfulfillment_tracking_urlfulfillment_locationfulfillment_shipment_statusfulfillment_processed_at

2Grouping Multiple Line Items (The Name Column)

This is the most common point of failure. In your CSV, each row represents a single line item (a single product), not the entire order.

To tell the system that multiple products belong to the exact same order, you must give them the exact same order number in the Name column.

Example

If Order #1001 had a T-Shirt and a Hat, your CSV will have two rows. Both rows must say #1001 in the Name column.

NameLine: TitleLine: Price
#1001Cotton T-Shirt25.00
#1001Baseball Hat15.00
#1002Running Shoes120.00

3Timestamps & Transaction Math

Historical orders are only useful if they appear on the correct dates in your Shopify Analytics. Ensure the Processed At column is filled out using the strict format: YYYY-MM-DD HH:MM:SS.

Shopify's Strict Math Requirement

Shopify will reject your order if the math does not perfectly equal the Transaction: Amount. For every order (grouped by Name), the system calculates:

(Line: Price × Quantity) + Taxes - Discounts = Transaction: Amount

Note: You only need to put the Transaction: Amount on the first row of an order. You can leave it blank for the subsequent rows of that same order.

4Exporting as CSV

Once your data is mapped, you must save the file in a format the system can read. If you are using Excel, go to File > Save As and select CSV UTF-8 (Comma delimited) (*.csv).

Why UTF-8? Standard CSVs can break special characters (like accents in customer names: René). UTF-8 preserves all global characters safely.

Phase 2

Import Historical Sales Data

  • Log in to your Shopify Admin.
  • Click on Apps and open Helios HistoriQ.
  • Locate the Import section at the top of the dashboard.
  • Click Add File and select your updated CSV file. Under the file name, it should recognize the data as Orders. (If it says "Unrecognized", check your header spelling!)
Phase 3

Shopify OrderCreate Configuration

Before importing, configure Shopify order behavior. These settings map directly to theOrderInput in the Admin GraphQL API.

sendReceiptSet to false to prevent Shopify order confirmation emails.
sendFulfillmentReceiptSet to false to prevent shipping/fulfillment emails.
inventoryBehaviourSet to BLANK if inventory has already been adjusted externally. Use this to avoid double-decrementing stock in Shopify.
Phase 4

Test Import (Dry Run Strategy)

Shopify does not support partial imports in orderCreate. Testing must be handled at the application level before mutation execution.

  1. Enable a preview / dry-run mode in your importer.
  2. Limit the batch size (e.g. first 3 records) in your own logic layer.
  3. Validate generated Shopify OrderInput payloads.
  4. Run a test GraphQL mutation against a development store.
  5. Confirm no unintended fulfillment or inventory side effects occur.
Phase 5

Validate Shopify Order Data

Open Shopify Admin → Orders and verify the imported test records.

  • Timestamps: Verify createdAt / processedAt align with expected import logic. Note: historical backdating may be limited depending on API usage.
  • Financial & Fulfillment Status: Confirm displayFinancialStatus and displayFulfillmentStatus match expected values (e.g. PAID, FULFILLED).
  • Order Totals Integrity: Validate subtotal + tax + shipping − discounts = totalPriceSet exactly matches Shopify-calculated totals.

Mapping Guide

Detailed Data Dictionary

Map your exact custom columns to the required CSV formats. Use the search bar below to instantly find your column.

1. Order Identity & Timestamps

Column Name
order_number
The primary human-readable identifier for the order inside Shopify (often shown as the order name). For historical sales imports, this is where you should place your legacy receipt, invoice, or transaction number from your old system. This allows staff to cross-reference historical paperwork or POS records with the Shopify order. Use a consistent format across all imported records (for example, prefix with "POS-" or "Legacy-"), and ensure that the values do not collide with existing or future web order numbers. Typically unique per order and very useful for searching in the Shopify admin.
Example Record
Sales-10045
Column Name
processed_at
CRITICAL: The exact date and time when the sale originally occurred. Shopify uses this timestamp to backdate the order in analytics, reports, and timelines. This should match the original transaction time from your legacy system as closely as possible. The format should be a complete timestamp (usually YYYY-MM-DD HH:MM:SS), in either the store's timezone or UTC depending on your import tool. Accurate values here ensure that historical sales appear in the correct reporting periods and that trends over time reflect real historical activity rather than the import date.
Example Record
2023-11-04 14:30:00
Column Name
status
Represents the financial state of the order in Shopify (for example, paid, pending, refunded, or partially_refunded). For historical sales imports where payment was already taken, this will almost always be paid. If you import orders that were partially refunded in your legacy system, you can use partially_refunded, but ensure that the order totals, line item amounts, and transaction records accurately reflect those refunds. This field affects financial reports and whether the order appears as outstanding or settled.
Example Record
paid
Column Name
fulfillment_status
Indicates whether items on the order have been fulfilled, that is, handed over to the customer or shipped. Common values include fulfilled, partial, and unfulfilled. For most backfilled historical in-store sales where customers already left with the items, you should use fulfilled so the orders do not appear in current picking or shipping queues. This field directly influences fulfillment views and whether staff believe there is remaining work on the order.
Example Record
fulfilled
Column Name
note
A free-form internal note stored on the order. Visible to staff inside the Shopify admin but not typically shown to customers. Ideal for importing cashier notes, special circumstances, references to external documents, or extra context from your old system. These notes are extremely helpful when staff need to understand historical edge cases or special handling that occurred with this order.
Example Record
Customer requested email receipt.
Column Name
tags
A set of comma-separated keywords used for organizing and filtering orders in the Shopify admin. Tags are searchable and power views, saved searches, and some workflows in apps. For historical imports, it is highly recommended to add at least one tag that clearly marks these records as imported history (such as Legacy_Sales or Historical). You can also include descriptive tags like Walk-in, Retail, or location tags to simplify segmentation later.
Example Record
Legacy_Sales, Walk-in

2. Customer Profile

Column Name
email
The contact email address of the buyer. Shopify uses this to associate the order with an existing customer profile or to create a new customer if none exists (depending on your import tool and settings). A consistent and accurate email address helps unify a customer's order history across online and in-person channels. If your legacy data includes multiple emails per customer, choose the one most commonly used for communication or online purchases.
Example Record
john.doe@example.com
Column Name
shopify_customer_id
The unique identifier of an existing Shopify customer, if you have already migrated customers before importing orders. When provided, this field explicitly links the order to that specific customer record, overriding the need to match by email. This is useful when you want to guarantee that historical orders attach to the correct profile even if email addresses have changed. If you do not have this ID or did not migrate customers separately, leave it blank and rely on the email field for matching.
Example Record
68778783ad298

3. Locations (Billing/Shipping)

Column Name
shipping_name
The full name of the recipient for the shipping address. Shopify can often split this internally into first and last name, but you should provide it as a clear, human-readable string (for example, "First Last" or "First Middle Last"). This name appears on packing slips, shipping labels, and within the order's shipping details, and is useful for staff and carriers when reviewing historical shipments.
Example Record
Jane Smith
Column Name
shipping_address1
The primary street address line for the shipping destination, such as house number and street name. This is the core location data for where the order was originally shipped. If the historical order was in-store pickup and no shipping actually occurred, you may leave this blank or use a store-location convention if your import process supports that. Keep city, province/state, and postal code in their own dedicated fields rather than embedding them here.
Example Record
123 Main St
Column Name
shipping_city
The city or locality for the shipping destination. Along with province/state, country, and postal code, this forms part of the full shipping address. Use consistent naming with your legacy system data so that geographic searches and region-based reporting remain reliable.
Example Record
Toronto
Column Name
shipping_province
The region, state, or province for the shipping destination. Depending on your importer, this might be a full name (for example, "Ontario") or a code. If you also supply shipping_province_code, that code typically takes precedence. Providing accurate provincial/state data helps with tax history, geographic reporting, and consistent region names.
Example Record
ON
Column Name
shipping_zip
The postal or ZIP code for the shipping destination. Important for regional tax logic, historical shipping calculations, and geographic reporting. Use the same formatting that customers would normally use (including spaces or hyphens where appropriate) to match standard postal conventions in that country.
Example Record
M5V 2K7
Column Name
shipping_country
The country of the shipping destination, often stored as a human-readable name. When possible, it is more reliable to use standardized ISO codes via shipping_country_code. Accurate country information ensures correct regional reporting and minimizes ambiguity when reviewing legacy international orders.
Example Record
CA
Column Name
billing_name
The full name associated with the billing address or payment method. This might differ from the shipping name if the buyer paid on behalf of someone else. Often the cardholder or account holder name from your legacy system. Accurate billing details provide context for reconciliation, fraud review, and understanding who actually paid for the historical purchase.
Example Record
Jane Smith
Column Name
billing_address1
The primary street address line for the billing address. Usually the address attached to the payment card or customer account in your legacy system. While historical billing addresses are not used for new charges in Shopify, they provide valuable context for customer records and risk reviews of old orders.
Example Record
456 Oak Lane
Column Name
billing_city
The city or locality for the billing address. Together with province/state, postal code, and country, it forms the full billing address that applied at the time of the original transaction. Use the same naming patterns from your legacy system for consistency in historical analysis.
Example Record
Austin
Column Name
billing_province
The region, state, or province for the billing address, either as a full name or code. Accurate billing province data can matter for tax/regulatory audits and understanding where past customers were located at the time of purchase.
Example Record
TX
Column Name
billing_zip
The postal or ZIP code for the billing address. Helpful when reviewing old orders for fraud analysis (for example, AVS checks in your legacy system) or understanding geographical distribution of your paying customers historically.
Example Record
78701
Column Name
billing_phone
The phone number associated with the billing address. Often the same as the customer contact number but may differ depending on payment method or account holder details. Useful for reconciliation, fraud review, and maintaining historical billing contact records.
Example Record
+15550123456
Column Name
billing_country
The country associated with the billing address. Often aligns with the issuing country of the payment card or the customer's primary residence at the time. Use a consistent name or code format that matches your import tool’s expectations.
Example Record
US
Column Name
shipping_line_title
A descriptive name for the shipping method used on the order, as seen by the customer or cashier (for example, "Standard Shipping", "Express Courier", "Local Pickup"). Preserves which option was selected at checkout in your legacy system and is useful when reviewing how customers historically chose and paid for shipping or pickup.
Example Record
Standard Shipping
Column Name
shipping_line_price
The total cost of the shipping method for the entire order, typically expressed as a decimal value in the store currency (for example, 10.00). This value should reflect what the customer actually paid for shipping at the time of purchase, excluding additional taxes if those are tracked separately. It contributes to the order total and must reconcile with your legacy order records for accurate financial history.
Example Record
10.00
Column Name
shipping_line_code
An internal reference code identifying the shipping method used, such as a short ID or system key from your legacy platform. Unlike the customer-facing title, this code is mainly for internal mapping and analytics. During migration, it helps you trace which old shipping rule or carrier service was applied to the order.
Example Record
std_ship
Column Name
shipping_line_source
Indicates the origin of the shipping record, usually referencing the system, channel, or method that produced it (for example, the name of your old POS or ecommerce platform). Capturing this aids in understanding how the shipping selection and pricing were generated historically, especially if you used multiple systems before Shopify.
Example Record
old_pos
Column Name
shipping_address2
A second line for the shipping address, commonly used for apartment numbers, suites, units, building names, or additional location info. Keeping this separate from Address 1 follows standard addressing conventions and improves readability for carriers and staff.
Example Record
Apt 4B
Column Name
shipping_phone
A contact phone number for the shipping destination. Used by carriers or staff if they need to coordinate delivery. For historical data, it also becomes another contact point on the customer profile. Use a consistent format (ideally with country code) so numbers are understandable internationally.
Example Record
+15550123456
Column Name
shipping_company
The company or organization name associated with the shipping address, if the order was shipped to a business. Particularly important for B2B or wholesale customers, as it helps staff identify which business received the goods in historical records.
Example Record
ACME Corp
Column Name
shipping_province_code
A standardized, typically two-letter ISO-style code for the state or province of the shipping address (for example, "NY" for New York, "ON" for Ontario). When supported by your import process, this is more reliable than free-form text because it avoids typos and inconsistent spellings. Accurate codes are important for region-based analytics and integrations that expect standard codes.
Example Record
NY
Column Name
shipping_country_code
A two-letter ISO 3166‑1 alpha-2 country code representing the shipping destination (for example, "US" for United States, "CA" for Canada). Strongly recommended over free-form country names, as it is unambiguous and works well with tax, shipping, and analytics tools that expect standard codes. Ensuring this code matches the true destination country is essential for accurate regional reporting.
Example Record
US

4. Cart / Products

Column Name
line_item_title
The exact product or variant name as it should appear on the order's line item, matching what the customer or cashier saw at checkout. For historical records, this preserves what appeared on old receipts. For gift cards or special products, ensure the title aligns with the corresponding product in Shopify if you want clean product-level reporting. Clear and consistent titles make it easy for staff to quickly understand what was sold when viewing old orders.
Example Record
Premium Cotton T-Shirt
Column Name
quantity
The number of units purchased for this specific line item. Typically a positive integer. For example, if the legacy order shows three of the same product sold on one line, quantity should be 3. This, multiplied by the unit price and adjusted by line-level discounts and taxes, must reconcile with your legacy line totals and overall order total.
Example Record
2
Column Name
price
The base price for a single unit of this line item, before any discounts or taxes are applied. Expressed as a decimal in the store currency (for example, 25.00). It should match the original per-unit selling price from your legacy system. When multiplied by quantity and then adjusted for discounts and taxes, it should yield the same financial outcome as recorded historically.
Example Record
25.00
Column Name
item_sku
The Stock Keeping Unit (SKU) identifier for the variant sold. This is crucial for connecting historical sales to present-day inventory and product records, because Shopify variants are frequently managed and reported by SKU. To maintain accurate inventory and product performance reports, ensure that SKUs in your imported orders match the SKUs on your active Shopify variants wherever possible.
Example Record
TSHIRT-WHT-MED
Column Name
barcode
The barcode (such as UPC, EAN, or another scannable code) associated with the variant that was sold. This may have been scanned at the register or stored in your legacy product record. While not mandatory, preserving barcodes on historical line items can help when auditing, reconciling inventory, or understanding how items were scanned and sold in-store. Ideally matches the barcode on the corresponding variant in Shopify.
Example Record
012345678910

5. Discounts Applied

Column Name
discount_title
A human-readable name or code for the discount that was applied, which might be an actual coupon code, a promotion name, or a manual override description from the cashier. Capturing this text helps staff understand why prices were reduced on historical orders and is useful for analyzing past promotions and discount behavior across channels.
Example Record
Walk-in 10% Off
Column Name
discount_type
Defines how the discount amount is interpreted. Common values: percentage (for a percent-off discount) or fixed_amount (a specific currency amount off). If percentage, the discount_amount is typically a whole number percent (for example, "10" for 10%). If fixed_amount, the amount is usually a currency value (for example, "5.00" for 5 units off in store currency). Correctly setting this ensures historical discounts reproduce the original pricing.
Example Record
percentage
Column Name
discount_amount
The value of the discount, interpreted according to discount_type. For a percentage discount, this is usually the numeric percentage (for example, 10 for 10%). For a fixed amount discount, this is a currency amount (for example, 5.00 for a five-dollar reduction). The values should line up with your legacy calculations so that combined with prices, taxes, and quantities, the imported order totals match what customers were originally charged.
Example Record
10

6. Taxes

Column Name
line_item_tax_price
The exact primary tax amount applied to this specific line item. Expressed as a currency value in decimal form (for example, 1.25). Capturing per-line tax is important when your legacy system calculated tax on individual items, and you want Shopify to match down to the cent. This amount should be consistent with the tax rate and the taxable base for that line.
Example Record
1.25
Column Name
tax_title
The descriptive name of the primary tax applied, such as a state or federal sales tax label. This name appears in the order's tax breakdown and helps staff understand which jurisdiction imposed the tax. Use names matching your old receipts or legacy system so your historical documentation remains consistent.
Example Record
State Sales Tax
Column Name
tax_rate
The decimal representation of the primary tax rate (for example, 0.05 for 5%). This rate, applied to the taxable subtotal, should produce the primary tax amounts you import (per line or overall). Matching this rate with your historical tax rules is necessary for reconciling Shopify and your legacy system.
Example Record
0.05
Column Name
tax_price
The total currency amount of the primary tax for the entire order, as a decimal (for example, 5.50). It should be equal to the sum of the primary tax applied across all taxed items. This field is central when reconciling historical tax collected on an order with your original system.
Example Record
5.50
Column Name
tax_2_title
The name of a secondary tax applied in addition to the primary one, such as a county or city tax. Many jurisdictions stack multiple taxes, and preserving a separate label for each helps you understand the full tax breakdown on historical orders.
Example Record
County Tax
Column Name
tax_2_rate
The decimal representation of the secondary tax rate (for example, 0.02 for 2%). As with primary tax rate, this is applied to the relevant taxable base to produce the secondary tax amount. Keeping this aligned with your legacy rates ensures your imported data reconciles.
Example Record
0.02
Column Name
tax_2_price
The total currency amount charged for the secondary tax across the entire order. Preserving a separate field for this helps you keep your historical multi-tax breakdowns accurate and auditable.
Example Record
2.20

7. Payment Transaction

Column Name
transaction_kind
Describes the type of money movement that occurred for this transaction. For historical sales migrations, this will almost always be sale, indicating a completed payment. In more complex setups you might see kinds like authorization, capture, or refund, but in a simple historical import you usually record only the final settled event. This is important for understanding the payment flow and distinguishing charges from adjustments.
Example Record
sale
Column Name
transaction_amount
The actual amount of money collected from the customer for this transaction, as a decimal in your store currency (for example, 54.20). For a final sale, this should match the grand total of the order (items + shipping + taxes - discounts). If it does not, there will be discrepancies between the payment record and the order totals. This must align perfectly with your legacy records for accurate financial history.
Example Record
54.20

8. Returns & Voids

Column Name
cancel_reason
Indicates the primary reason why an order was canceled or voided in your legacy system. Typical values include customer (customer changed mind), inventory (out of stock), fraud, declined (payment failed), or other. Capturing this helps analyze why orders historically failed or were reversed and can guide future process improvements.
Example Record
customer
Column Name
cancel_restock
Indicates whether items from a canceled or refunded order were returned to inventory. Often stored as a boolean-like string such as "TRUE" or "FALSE". Set to true if the item was physically returned and put back into stock; false if it was not. Important when comparing legacy stock levels to Shopify inventory and understanding stock movements from historical returns.
Example Record
FALSE
Column Name
cancel_staff_note
An internal note entered by staff explaining the return, cancellation, or refund—such as the customer's explanation, product condition, or approvals involved. Preserving these details is extremely useful for investigating disputed transactions and understanding how returns were handled historically.
Example Record
Customer brought it back, wrong size.
Column Name
cancel_notify_customer
Controls whether the customer should be notified by email about the cancellation or refund when the action is performed in Shopify. For historical imports, you typically leave this blank or in a state that prevents notifications, so you do not send unexpected emails about old orders. Only set this if you have a specific strategy to communicate about historical adjustments.
Example Record
Leave blank to disable notification

9. Advanced Fulfillment

Column Name
fulfillment_tracking_company
The name of the shipping carrier that handled the shipment (for example, USPS, UPS, FedEx, DHL, or a local courier). Recording the correct carrier allows Shopify to display more meaningful tracking information and gives staff better context when reviewing historical shipments and delivery performance.
Example Record
USPS
Column Name
fulfillment_tracking_number
The tracking number assigned by the carrier for this shipment. If multiple tracking numbers exist for one order (for example, split shipments), some import processes allow separating them with semicolons. Tracking numbers are highly valuable for validating that goods were dispatched as recorded and for resolving delivery disputes close to the time of migration.
Example Record
1Z9999W99999999999
Column Name
fulfillment_tracking_url
A direct URL to the carrier's tracking page for this shipment. Shopify can display this link on the order so staff can quickly open carrier tracking. For older shipments the URL may eventually expire, but having it stored is still useful for recently imported historical orders.
Example Record
https://tools.usps.com/...
Column Name
fulfillment_location
The name of the Shopify location that fulfilled the order (for example, a warehouse, retail store, or distribution center). This should map to an actual Shopify location, not to third-party fulfillment services that you do not want to double-ship from. For historical imports, use consistent names to clearly indicate where items were shipped or picked up, which improves location-based reporting and operational analysis.
Example Record
Main Warehouse
Column Name
fulfillment_shipment_status
Represents the shipment's delivery status, often mirroring carrier statuses such as delivered, in_transit, out_for_delivery, or failure. Mapping these correctly allows Shopify's order timeline to reflect what actually happened to each package historically and supports analysis of fulfillment performance over time.
Example Record
delivered
Column Name
fulfillment_processed_at
The exact date and time when the fulfillment event historically occurred—when the order was packed and handed off to the carrier or picked up. Like the order's main processed_at, this timestamp is used to backdate the fulfillment timeline in Shopify. Accurate values here give you a precise historical log of how long it took to ship or hand over orders after purchase.
Example Record
2023-11-06 14:30:00

Support

Troubleshooting & Common Errors

Encountered an issue during your test import? Check these common solutions.


Additional Resources

Encountered an issue during your test import? Check these additional resources.

Wrap Up

Post-Migration Checklist

Once your import shows as Completed, use this checklist to confirm everything looks correct in Shopify.

1. Review Analytics

Open Shopify Analytics → Reports and check key metrics like sales and orders. Imported data may take some time to fully reflect in historical reports depending on how the orders were created.

2. Check Customer Records

Search for a customer included in the import and confirm that their historical orders appear in their timeline.

3. Secure Your Files

Save your original import file in a secure location for backup, auditing, or compliance purposes.

Still Need Assistance?

Need help? Contact support and we’ll assist you as soon as possible.