Files
descrybe/docs/shopify-connector.md
T
greeneclipse 8580c996c3 Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
2026-08-09 22:47:43 +02:00

5.7 KiB
Raw Blame History

Shopify connector

Descrybe v2 connects Shopify as a first-class store source alongside WooCommerce.

UI: /stores (hub) → /stores/shopify (setup). /shopify redirects to the setup page.

What syncs

Data Direction Notes
Products Push Processed Descrybe products → Shopify Admin API create/update (queued / scheduled — not store webhooks)
Orders Pull Queued / scheduled pull into shopify_orders / shopify_order_items (not live webhooks)
Reviews Not available (Shopify has no first-party product reviews Admin API)
Inbound webhooks Not received; do not register Shopify webhook URLs at Descrybe until a full HMAC receive path ships (docs/store-connectors.md)

As of 1 January 2026, Shopify no longer creates new custom apps in Admin → Develop apps. New apps are created in the Dev Dashboard, installed on the store, then authenticated with the client credentials grant (short-lived Admin API tokens, ~24h).

  1. Open the Dev Dashboard → AppsCreate appStart from Dev Dashboard (UI deep-links this).
  2. Create a version: App URL can be the default API-only home; scopes at least read_products, write_products, read_ordersRelease.
  3. From the app Home tab → Install app on your store (approve scopes).
  4. App Settings → copy Client ID and Client secret.
  5. In Descrybe /stores/shopify: enter shop domain (your-store or your-store.myshopify.com), paste Client ID + secret, enable sync → SaveTest Connection.
  6. Queue product sync and orders sync. Run the worker so pending flags are claimed.

Descrybe exchanges Client ID + secret for an access token on save and refreshes automatically before expiry (no migration; secrets live encrypted in access_token + sync_options).

Legacy Admin API token (shpat_…)

Custom apps created in Shopify Admin before January 2026 still expose a permanent Admin API access token. The connect form has a “legacy token” path for those. Prefer Client ID + secret for anything new.

Still manual (no one-click App Store install)

  • Creating the Dev Dashboard app, releasing a version, and installing it on the merchant store
  • Approving scopes in Shopify Admin when scopes change
  • Collaborator accounts cannot use the Dev Dashboard — the store owner (or staff with Develop permission) must create the app
  • Client credentials only work when the app and store are in the same Shopify organization (see Shopifys shop_not_permitted docs)

Shop domain must be the *.myshopify.com admin host. Custom storefront domains are rejected (Admin API always uses myshopify.com). SSRF guards block IPs, localhost, and private ranges.

Environment variables (optional live path)

Set in process env or untracked .env (never commit secrets):

Variable Purpose
SHOPIFY_SHOP_DOMAIN Shop name or name.myshopify.com
SHOPIFY_ACCESS_TOKEN Admin API access token (legacy / ops scripts)
SHOPIFY_API_VERSION Default 2024-10
SHOPIFY_DRY_RUN When true, treat as dry-run (UI also has a Dry run checkbox)

Aliases are not required; credentials saved via the UI are encrypted at rest (CREDENTIALS_ENCRYPTION_KEY / APP_ENCRYPTION_KEY — see ops-runtime.md).

No live shop? Dry-run / mock

  • In the UI: enable Dry run, or set access token to exactly dry-run.
  • Dry-run skips live HTTP calls: test connection returns a mock shop; product create/update and a sample order page succeed in-process.
  • Unit tests in internal/shopify cover domain SSRF guards, token encryption, client-credentials parsing, and dry-run client behavior (no network).

APIs

Method Path Notes
GET /api/shopify Config + sync badges (no secrets). Includes auth_mode, has_client_credentials.
PUT /api/shopify Save shop domain + (client_id/client_secret or access_token) + api_version + dry_run
POST /api/shopify/test Live or dry-run shop.json (refreshes client-credentials token if needed)
POST /api/shopify/sync Queue product push
POST /api/shopify/sync-orders Queue orders pull
GET /api/shopify/orders List synced orders

Worker

cmd/worker claims pending Shopify jobs after WooCommerce:

  • productsshopify.Service.SyncCompany
  • ordersshopify.Service.SyncOrders

Scheduled enqueue (every 15m ops tick) marks enabled configs whose last_synced_at is older than the interval (default 6h).

Schema

Migration apps/api/sql/schema/017_shopify.sql:

  • shopify_configs — shop domain, encrypted access token, api version, sync_options JSONB
  • shopify_orders / shopify_order_items — pulled order data

Client credentials metadata (auth_mode, client_id, encrypted client_secret_enc, token_expires_at) is stored in sync_options (no extra migration).

Apply with make migrate (or scripts/migrate.ps1 on Windows).

Product matching

  1. Cached Shopify product id in sync_options.product_ids (keyed by Descrybe processed product UUID).
  2. Else GraphQL productVariants(query: "sku:…").
  3. Else create a new product with a single variant (SKU/price/barcode) and a descrybe.product_id metafield.