Tom Sailors Contact
Guide · Migration

How to migrate customers to Shopify without losing loyalty points

Published 2026-08-01 · Updated 2026-08-01

Customer migrations fail quietly: the records arrive, the loyalty balances don't, and the first complaint comes from a top customer whose 12,000 points read zero. Shopify has no native points field, so a migration that preserves loyalty data has to decide where balances live and prove they arrived. This is the process.

Where loyalty data lives in Shopify

Customer metafields. A number_integer metafield such as loyalty.points_balance holds the balance; companion metafields hold lifetime value, tier, or join date. Metafields are readable from theme code (customer.metafields.loyalty.points_balance), checkout extensions, Shopify Flow, and any loyalty app you adopt later — which is what makes them the storage choice: the data outlives whatever reads it today.

Step 1 — validate the export before anything imports

Read the legacy export and reject problems while they're cheap: malformed emails, duplicate rows, missing balance fields, encodings that mangle names. Every record that enters the import clean is a record you don't reconcile by hand later. Duplicates deserve a decision, not a default — merge, skip, or flag, chosen per segment.

Step 2 — import in batches with tags and metafields together

One mutation creates the customer with segmentation tags and loyalty metafields attached:

mutation ImportCustomerWithLoyalty($input: CustomerInput!) {
  customerCreate(input: $input) {
    customer { id tags metafields(first: 5) { edges { node { namespace key value } } } }
    userErrors { field message }
  }
}

CustomerInput accepts metafields inline, so the balance is written in the same call that creates the record — no window where a customer exists without their points. Batch the file, record every userErrors response, and make the job resumable: a 40,000-record import will be interrupted at least once, and a rerun must not duplicate customers.

The customer CSV importer also accepts metafield columns, which covers a small clean file. Past a few thousand records, the API path wins on error reporting alone.

Step 3 — audit against the source

After the batches finish, reconcile: for each source row, fetch the customer and compare email, tags, and each metafield value against the file. Write mismatches to a report. The audit converts "the import ran" into a per-record account of what arrived and what needs follow-up — the same discipline as a subscription migration's verification pass.

Step 4 — connect the balance to something

A migrated balance nobody can see or redeem is a liability without a program. Point the storefront at the metafield — a balance display in the account area, a redemption path, or a loyalty app configured to read the imported values. The custom loyalty program guide covers the build that runs on these metafields directly.

Migrating customers with loyalty history?

Email Tom the record count, the source platform, and how points are structured — flat balance, tiers, or expiring — those three facts determine the import plan.

Email Tom →