DataFirefly Shopify Migrator — Complete guide
Migrate your PrestaShop 8/9 catalog to Shopify — products, variants, customers, collections, CMS pages, features and 301 redirects, in CSV or API mode.
Overview
DataFirefly Shopify Migrator is a PrestaShop 8 and 9 module that exports your entire catalog to Shopify, with two modes to choose from: CSV (generates files ready to import manually via the Shopify admin, no API key required) or API (direct push to a connected Shopify store via the Admin REST API 2026-04).
The module handles eight entities, typically migrated in this order:
- Products — full product records, variants up to 3 attribute groups, images, stocks, prices excluding or including tax, SEO meta preserved via global title_tag/description_tag metafields
- Collections — PrestaShop categories converted to custom collections with image and description
- CMS Pages — PrestaShop pages converted to Shopify pages with slug and SEO meta
- Customers — customer records + default address + order statistics, tagged imported-prestashop
- Orders — consultative CSV export only (Shopify does not accept native order imports via standard CSV)
- 301 Redirects — mapping table from old PrestaShop URLs to new Shopify URLs to preserve search rankings
- Repair images and Variant images — two repair jobs to recover images Shopify silently lost during async fetch, and to wire each Shopify variant to its image
- Features → Metafields — pushes PrestaShop product features as Shopify metafields with automatic Metafield Definition creation via GraphQL
The architecture is asynchronous and job-based: each migration creates a job in the database, then processed in configurable batches via a token-protected cron worker. Shopify rate limits are respected automatically (1.8 req/s, 429 retry), and a persistent ID mapping in the database links PrestaShop identifiers to Shopify identifiers, enabling redirects and avoiding duplicates on re-runs.
Requirements
- PrestaShop 8.0 to 9.x
- PHP 7.4 to 8.3
- For API mode: a target Shopify store (Basic plan is enough), a Shopify Partners account or access to the Shopify Dev Dashboard
- For cron mode: the ability to schedule a URL on your host (crontab, cron-as-a-service, or Plesk/cPanel)
- Server side: PHP curl and iconv extensions enabled
Installation
- Download the ZIP from your DataFirefly customer account (Downloads section of the product page).
- In the PrestaShop back office, go to Modules → Module Manager → Upload a module, drop the ZIP.
- Click Install. The module creates three tables (jobs, mapping, log) and a dedicated tab under Advanced Parameters → Shopify Migrator.
- Click Configure to access the main interface.
Choosing between CSV mode and API mode
CSV mode
The module generates CSV files in the native format expected by Shopify Admin (Products Import, Customers Import, URL Redirects Import). You download each file from the Jobs tab and import it manually into Shopify.
Advantages: no API key to configure, ability to inspect and adjust the files before import, very fast processing on the PrestaShop side.
Limitations: Shopify collections have no native CSV import (the generated file serves as a reference), and orders are never importable via standard CSV on the Shopify side.
API mode
The module sends each entity directly to your Shopify store via the Admin REST API 2026-04, with rate limit handling, automatic retry on 429 errors, and persistent ID mapping for automatic redirects and idempotent re-runs.
Advantages: end-to-end migration in one command, redirects pushed directly, collections created automatically with product attachment, perfect for large catalogs.
Limitations: requires a Shopify app with the right scopes, and some Shopify organizations created after April 2025 are GraphQL-only (the module remains REST-compatible for standard organizations).
API mode: creating the Shopify app
Creating the app in the Dev Dashboard
- Log in to the Shopify Dev Dashboard (dev.shopify.com/dashboard) with your Partners account.
- Click Create app, name it (for example “Migrator”), and confirm.
- On the configuration screen, the App URL can be left to any valid HTTPS value. It is only used for OAuth, which does not concern our case.
Configuring scopes
In Configuration → Admin API integration → Configure access scopes, enable the following scopes:
read_products,write_productsread_customers,write_customersread_content,write_contentread_inventory,write_inventoryread_online_store_pages,write_online_store_pagesread_online_store_navigation,write_online_store_navigationwrite_metaobject_definitions(only if you use the Features → Metafields entity)
Click Save.
Installing on the target store
- In Distribution, choose Custom distribution and add your target Shopify store.
- Click the generated install link, which opens the merchant consent screen on the Shopify Admin side.
- Confirm the installation: you reach the final app screen.
Retrieving Client ID and Client Secret
In Settings → Credentials of the app, copy the Client ID, then click the eye icon next to Secret to reveal and copy it.
API mode: configuring credentials
In the module’s Settings tab, choose the Shopify Admin REST API mode, then fill in:
- Shopify store domain — either the short name (
my-store) or the full domain (my-store.myshopify.com). - API version — defaults to 2026-04, the current stable version.
- Authentication method — two choices are available:
Method 1: Admin access token
For the rare cases where you already have a valid Admin API token (legacy custom app or token obtained manually via OAuth). Paste the token in the dedicated field and save.
Method 2: Client Credentials Grant (recommended)
The module exchanges your Client ID + Client Secret for an Admin API access token via the OAuth Client Credentials Grant flow. The token is cached (24 h), automatically refreshed less than 5 minutes before expiration. No manual intervention required during migration.
Fill in both fields and save. Click Test connection: the module shows your Shopify store name and the time remaining before token expiration.
shop_not_permitted. In that case, either link the store to your Partners organization, or obtain a token manually via Authorization Code Grant OAuth (outside the module’s scope).
Products migration
Product export is the most complex. It handles products, variants (up to 3 attribute groups as Shopify allows), images (absolute URL from your PrestaShop), stocks, prices, manufacturers used as vendor, categories converted to tags and type, SEO meta preserved via global.title_tag and global.description_tag metafields.
Starting the job
- In Run a migration, select the Products card.
- Click Create export job. The job appears in the Jobs tab list with the pending status.
- If you configured the cron, the worker picks it up within the next minute. Otherwise click the Run now button to advance it synchronously (limited by PHP timeout, around 30 seconds).
Progress tracking
The Jobs tab auto-refreshes every 10 seconds. Each row shows the status (pending/running/done/failed/cancelled), progress percentage, success and error counts, and a collapsible log button that displays the last 30 log lines.
CSV mode case
The file job_X_products.csv is generated in Shopify Products Import format. Download it from the jobs list, then in Shopify Admin go to Products → Import and drop the file. Shopify handles the processing on its side, with an email notification when done.
Collections migration
PrestaShop categories (excluding root and category ID 1) become Shopify custom collections, with their title, description, image, SEO meta and the cleaned slug. In API mode, products already migrated are automatically attached to each collection via the /collects.json endpoint.
CMS pages migration
Active PrestaShop pages are exported as Shopify pages with their title, HTML content (relative image URLs are automatically resolved to absolute URLs pointing to your PrestaShop domain), slug and SEO meta.
Customers migration
For each active, non-deleted customer, the module exports the name, email, default address, total spent, valid order count, and newsletter opt-in. Each customer receives the imported-prestashop tag for easier later filtering.
Orders migration (CSV only)
Orders export is consultative: Shopify does not offer native order import via standard CSV. The generated file contains all useful information for archive or analysis: reference, date, status, customer, billing and shipping addresses, currency, totals excluding and including tax, carrier, tracking, and one line per product purchased.
You can filter by date range in the job creation form (Orders from and Orders to fields).
For Shopify Plus users, third-party tools like Matrixify accept this format as input for true re-importation.
301 redirects migration
This is the key point to preserve your search rankings on domain switch day. The module reads the mapping table built by the previous exports (products, collections, pages) and generates a two-column CSV in the native Shopify URL Redirects format, with old PrestaShop URLs in the first column and new Shopify URLs in the second.
In API mode, the module directly pushes each redirect via POST /redirects.json. In CSV mode, import the file in Shopify Admin via Online Store → Navigation → URL Redirects → Import.
Exclusion filters (v1.1)
Two optional filters allow you to exclude products from the export, configurable in Settings → Product filters (exclusions).
Exclude categories
Text field with a comma-separated list of PrestaShop category IDs. A product belonging to at least one of these categories is excluded from the Products export. The categories themselves remain migrated by the Collections entity (useful if a technical category should not be displayed but may contain products).
Exclude reference prefixes
Text field with a comma-separated list of prefixes. Any product whose reference starts with one of these prefixes is excluded. Useful to skip internal products (NS for non-sellable, HB for off-business, OBSOLETE- for discontinued ranges, etc.). Prefixes are case-insensitive.
Repair images (v1.3)
Shopify downloads images asynchronously after creating a product: it fetches the URL you provided, and if it fails silently (timeout, blocked URL, file too large, format rejected), it returns no error. The product is created “success” on the API side but without images.
The Repair images entity fixes these cases. For each product in the mapping:
- GET
/products/{shopify_id}/images.jsonto count current images on Shopify. - Read the corresponding images on PrestaShop.
- If Shopify already has as many images as PS → the product is skipped.
- Otherwise: delete partial Shopify images, then upload each PS image via base64 attachment (synchronous mode, Shopify confirms creation immediately), with URL fallback for files larger than 3 MB.
API mode required. Idempotent: you can re-run the job as many times as needed.
Variant images (v1.4)
Once main images are in place, each Shopify variant still needs to be tied to its corresponding image. The Variant images entity handles this: for each product in the mapping, it queries the list of variants and images on Shopify, then cross-references with PrestaShop’s product_attribute_image relations.
PS variant → Shopify variant matching uses SKU first (variant reference), with a fallback by option tuple (option1/option2/option3 lowercase) if reference is empty.
PS image → Shopify image matching uses position alignment: the N-th PS image corresponds to the N-th Shopify image. This holds as long as you have not manually reordered images in the Shopify admin.
Idempotent: a variant already on the correct image_id is skipped (logged already_ok). The log counts per product: assigned / already_ok / missing_image / missing_variant.
Features → Metafields (v1.5)
PrestaShop product features (Catalog → Attributes & Features → Features) are pushed as Shopify metafields under the custom namespace, with automatic Metafield Definition creation so they are editable from the Shopify admin.
Phase A: Definition creation (first batch)
On the first batch of the job, the module lists all distinct features in the shop and creates a Metafield Definition for each via the metafieldDefinitionCreate GraphQL mutation. Existing definitions (TAKEN or DUPLICATE_KEY codes) are silently ignored.
Phase B: value push (each batch)
For each product in the mapping, the module lists existing custom.* metafields, then for each PS feature performs an upsert: PUT if the key exists with a different value, POST if the key does not exist. Already identical values are skipped.
Name → key conversion
The PrestaShop feature name is converted to a Shopify metafield key by ASCII transliteration, lowercasing, replacing non-alphanumeric characters with underscores, truncation to 30 characters. Examples:
Matière principalebecomesmatiere_principaleWeight (kg)becomesweight_kgColorbecomescolor
write_metaobject_definitions in the Shopify app, Phase A fails. Phase B still works but metafields are not visible in the Shopify admin UI in an editable way. To add it without reinstalling the app, add the scope in Configuration, save, then uninstall/reinstall the app to refresh merchant consent.
Cron worker
The module exposes a token-protected front endpoint that processes one job per tick, at 20 batches per tick. The full URL with token is displayed in the Run a migration tab, with a copy button.
Sample crontab entry for one tick per minute:
* * * * * curl -s "https://your-prestashop.com/index.php?fc=module&module=dfshopifymigrator&controller=cron&token=YOUR_TOKEN" > /dev/null
Without configured cron, you can always advance a job manually with the Run now button in the jobs list (synchronous advancement, limited by PHP back-office timeout, about 30 seconds).
Recommended job order
For a complete migration without surprises, run the jobs in this order:
- Products — creates the PS→Shopify mapping for products, used by all subsequent steps.
- Collections — creates the mapping for categories and automatically attaches products.
- Pages — creates the mapping for CMS pages.
- Customers — independent of the rest.
- Orders — consultative CSV only, run at your own pace.
- Repair images (if needed) — fixes images lost during Shopify async fetch.
- Variant images — re-associates each variant with its image.
- Features → Metafields — pushes product features as visible metafields.
- Redirects — last, consumes all the mapping built above.
Known limitations (v1)
- Only one language is exported per migration (the language selected in Settings). v2 will add mapping of PrestaShop languages to Shopify Markets and Translate & Adapt.
- Orders are exported as consultative CSV only.
- Customer passwords are not migrated.
- Variants are limited to 3 attribute groups (Shopify Option1/Option2/Option3 limit).
- Images are served from the public URL of your PrestaShop: keep your PS online during Shopify import, and at minimum during any Repair images job.
Troubleshooting
Shopify API error: Not Found
First, check the API version field in Settings: it must be 2026-04 (older versions like 2024-10 are retired). Also check that your app is properly installed on the target store in Distribution.
Shopify API error: Invalid API key or access token
The token has expired (CCG: 24 h lifetime, automatically refreshed) or the app has been uninstalled. Click Test connection to force a CCG token refresh. If the error persists, go to Shopify Admin → Apps and sales channels and check that the Migrator app is in the list of installed applications.
This action requires merchant approval for write_X scope
You modified the scopes after the initial app installation, the merchant did not get to approve them. Uninstall the app in Shopify Admin then reinstall it via the Distribution link in the Dev Dashboard. The merchant consent screen will reappear with the new scopes.
shop_not_permitted during CCG exchange
Your Shopify store is not in the same organization as your Dev Dashboard app. Either link the store to your Partners organization, or use an Admin token obtained manually (Authorization Code Grant OAuth, outside the module’s scope).
Cardinality violation: Subquery returns more than 1 row
Bug fixed in v1.2.1. Update to the latest module version.
Many Shopify products arrived without images
This is Shopify’s documented behavior for images pushed via URL. Run the Repair images job in API mode: it detects products with fewer images than PS and republishes everything in base64 (synchronous mode, guaranteed arrival).
Many “missing_variant” entries in Variant images logs
The Shopify variant SKU does not match the PrestaShop product_attribute reference, and the option tuple fallback did not match either. Check that your PS variants have references filled in, or contact DataFirefly support for a custom matching adjustment.
Resources
- DataFirefly Shopify Migrator product page (downloads, purchase, license)
- Official Shopify Admin REST API documentation: shopify.dev/docs/api/admin-rest
- Shopify Client Credentials Grant documentation: shopify.dev/docs/apps/build/authentication-authorization/access-tokens/client-credentials-grant
- DataFirefly support: hello@datafirefly.com