Shopify Import¶
Import products, customers, and orders from Shopify — either from Shopify's CSV exports or live from the Shopify Admin API. Use it when migrating a store off Shopify onto Vectis: both source modes normalize to the same field names, so one reviewed mapping works for either, and Shopify metafields are auto-routed into Vectis custom fields so a customized shop migrates without manual mapping.
At a glance
| Extension id | shopify |
| Category | migration |
| Version | 0.1.0 |
| Provides | Import provider (products, variants, images, customers, orders) |
| External account | Shopify Admin API access token (Admin API mode only; CSV mode needs none) |
What It Provides¶
- An import provider with key
shopify(label "Shopify"), registered on the strategy resolver when the extension activates. It appears in the provider list of the admin Import Wizard via theimportProvidersGraphQL query. - Two source modes:
csv(Shopify CSV exports) andadmin_api(Shopify Admin REST API). - Five entity types:
product,variant,image,customer,order, with a dependency DAG — variants and images require products; orders require customers, products, and variants. Runs import dependencies before dependents, and the wizard flags unselected prerequisites. - Default field mappings per entity (e.g. product
name←Title,slug←Handle,description←Body (HTML)stripped of HTML tags,statusmappedactive→published/draft→draft/archived→archived). Discoveredmetafield.*source fields are automatically routed intocustom_fields. - Import runs execute through the core
ImportRunWorkflowTemporal workflow (Building Extensions covers the strategy surface). The extension itself registers no workflows, webhook endpoints, admin pages, or GraphQL fields of its own.
Setup¶
- The extension loads at boot; it should appear under Settings > Extensions.
- Open Settings > Import Wizard in the admin (
/settings/import). - Provider step: pick Shopify.
- Entities step: choose what to import. The wizard flags unselected prerequisites (e.g. picking
orderwithoutproduct/variant/customer) and offers to add them, so cross-entity references stay linked. - Connect step:
- CSV / spreadsheet upload — upload the Shopify export CSV for each selected entity. The products export backs the
product,variant, andimageentities; separate customers and orders exports back the rest. - Live Admin API — enter the connection config as JSON:
shop_domain,access_token, and optionallyapi_version(see the reference below).
- CSV / spreadsheet upload — upload the Shopify export CSV for each selected entity. The products export backs the
- Map & review step: the provider's default mapping is pre-filled per entity; unmapped source fields can be routed into
custom_fields, and each entity's mapping can be saved as a reusable import profile. - Dry run step: previews create/update/skip/fail counts without writing anything — every row runs in a savepoint that a dry run rolls back.
- Run step: executes the import.
There is no separate test-connection step in the wizard: bad credentials surface when the wizard first discovers source fields on the way into Map & review. (The connector implements a test_connection hook that fetches shop.json, but no wizard step currently invokes it.)
Configuration Reference¶
This provider has no extension-level config_schema — connection details are entered per run in the wizard's Connect step and are not stored (the persisted import-run record keeps the plan, not the connection config). Per source mode:
CSV mode
| Key | Type | Required | Secret | Description |
|---|---|---|---|---|
contents |
object | No | No | Shopify CSV exports keyed by products/customers/orders |
Admin API mode
| Key | Type | Required | Secret | Description |
|---|---|---|---|---|
shop_domain |
string | Yes | No | e.g. acme.myshopify.com |
access_token |
string | Yes | Yes | Shopify Admin API access token, sent as X-Shopify-Access-Token |
api_version |
string | No | No | Defaults to 2024-01 |
Permissions¶
The manifest declares no permissions of its own. Running imports and saving mapping profiles require the core import_export.import permission.
Operational Notes¶
- Admin API pagination — cursor pagination via the
Linkresponse header, 250 records per page. Requests use a 60-second HTTP timeout. - Metafields — the API connector surfaces product and customer metafields as
metafield.<namespace>.<key>source fields; the default mapping auto-routes them intocustom_fields. - CSV reshaping — Shopify's products export is multi-row-per-product: the first row of a
Handlegroup is the product, rows with aVariant SKUbecome variants, and rows with anImage Srcbecome images. The orders export is grouped byName: the first row of a group carries the order-level fields, and every row with aLineitem nameorLineitem skucontributes a line item. Shopify has no standard collection CSV export, so collections are not an importable entity here. - Orders import as historical records — the default (and currently only working)
order_import_modeishistorical: order and line rows are written without triggering payment, inventory, or fulfillment workflows, and imported orders are stamped_importedin metadata. Selectinglivemode is rejected by the order loader (it raises per row instead of silently re-entering workflows). - Order lines must resolve to variants — each order line is matched to an existing variant by SKU; an unresolvable line fails that order's row. Import products and variants before orders.
- Idempotent re-runs — each successfully imported row records a
(provider, entity, external_id) → internal idcrossref, and loaders upsert by natural key: slug for products, SKU for variants, email for customers, order number for orders. In the default mapping those keys and the external ids come from the same source columns (Handle,Variant SKU,Email,Name), so re-running an import updates existing records instead of duplicating them. - Failure isolation — every row runs inside a database savepoint, so one bad row cannot poison the rest; failures are collected into the run's error report.
- Durability — runs execute as the core
ImportRunWorkflowon thevectis-mainTemporal task queue, with a 30-minute activity timeout and up to 3 retry attempts.
See also: WooCommerce Import, Building Extensions.