When a brand moves from PrestaShop to Shopify, its customer history has to come along: accounts, addresses and years of past orders. Shopify can import all of it through the Admin GraphQL API. By default, it will also politely email every customer an account invitation and a receipt for an order they placed three years ago.

For a store with tens of thousands of customers, that is not a bug report. It is a crisis. So the one hard requirement for this migration app was silence.

Making the mistake impossible, not unlikely

A checkbox or a careful developer is not a guarantee. I wanted the code itself to make sending mail impossible, so the app has exactly one place that creates orders, and the receipt options there are hardcoded:

// The only code path that creates orders (simplified)
const options = {
  sendReceipt: false,
  sendFulfillmentReceipt: false,
  inventoryBehaviour: "BYPASS",
};

Customers are created without a password or an invited state, so Shopify has no reason to send an invitation. And a guard test fails the build if any of the invite mutations is ever referenced anywhere in the code. If someone adds one in a year, the release stops before it reaches a store.

Dry run first, always

The merchant uploads three PrestaShop exports. Nothing is written yet: the app first shows what it parsed, previews of every file, customers it could not match, missing SKUs and rows it will skip.

Only then can they start the import, behind a confirmation that repeats the no-email promise and the exact shop domain it will write to. Customers go in first, then orders from oldest to newest, with live progress and a cancel button. Every run can be repeated safely and ends with a CSV report of every source row.

Built once, used twice

The app ran for the Swiss store and then for the UAE store. Behind it are 17 test suites, and 53 of its 56 commits are mine. The number I am proudest of is the one nobody sees: zero customer emails.

Further reading