AACsearch
Connectors & Widget

Shopify Connector

Shopify connector for AACsearch — OAuth install flow, webhook-driven delta sync and product mapping. Early preview.

Status: Early preview. The Shopify connector source lives at packages/shopify-connector/ in the AACsearch monorepo. It is not yet published as a Shopify App Store listing — install is manual via a custom app or the development store.

The Shopify connector follows Template B (TypeScript server-side connector) from wiki/tasks/cms-platform-expansion.md. It uses Shopify's OAuth flow to obtain a per-shop access token, encrypts that token at rest, and reacts to product webhooks to push delta syncs into AACsearch.

Supported scope

  • Shopify online stores (Basic, Shopify, Advanced plans).
  • Products, variants, collections and inventory levels.
  • Multi-currency catalogs via Shopify Markets — exported as alternative prices in attributes.price_by_currency.
  • Locales configured under Shopify Markets — exported as separate documents per locale.

Headless Shopify (Hydrogen / Storefront API) is supported but requires manual sync from your own storefront server using the Custom Connector approach.

Architecture

The connector runs as a Node.js service alongside the AACsearch monorepo. The router is mounted under /api/connectors/shopify:

Shopify storefront
    │ (admin install + webhooks)

packages/shopify-connector/src/router.ts
    ├── /oauth/install         ← initiates OAuth flow
    ├── /oauth/callback        ← receives auth code, stores encrypted token
    ├── /webhooks/products/*   ← product create/update/delete
    ├── /webhooks/inventory/*  ← inventory level changes
    └── /sync/full             ← manual full resync trigger


AACsearch Connector API

Files of interest:

  • packages/shopify-connector/src/oauth.ts — Shopify OAuth 2.0 flow
  • packages/shopify-connector/src/crypto.ts — AES-256-GCM token encryption
  • packages/shopify-connector/src/product-mapper.ts — Shopify entity → SyncProductInput
  • packages/shopify-connector/src/webhooks.ts — HMAC verification + debounce
  • packages/shopify-connector/src/sync.ts — full and delta sync drivers

Installation (current preview)

The public Shopify App Store listing is part of the v0.7 roadmap. Until then, install via a custom app on your Shopify store:

  1. In your Shopify admin, open Settings → Apps and sales channels → Develop apps → Create an app.
  2. Configure Admin API access scopes: read_products, read_inventory, read_collections, read_locations.
  3. Install the app and copy the Admin API access token.
  4. In your AACsearch dashboard, create a connector token (Connectors → New Connector Token) bound to the index you want products indexed into.
  5. Add a .env entry on the AACsearch server pointing the Shopify connector at your store:
SHOPIFY_SHOP_DOMAIN=mystore.myshopify.com
SHOPIFY_ADMIN_ACCESS_TOKEN=shpat_xxxxxxxx
AACSEARCH_CONNECTOR_TOKEN=ss_connector_xxxxxxxx
AACSEARCH_PROJECT_ID=org_xxxxxxxx
  1. Register webhooks from the Shopify admin or via API:
TopicAddress
products/createhttps://your-aacsearch.example.com/api/connectors/shopify/webhooks/products/create
products/updatehttps://your-aacsearch.example.com/api/connectors/shopify/webhooks/products/update
products/deletehttps://your-aacsearch.example.com/api/connectors/shopify/webhooks/products/delete
inventory_levels/updatehttps://your-aacsearch.example.com/api/connectors/shopify/webhooks/inventory/update
  1. Trigger an initial full sync from the AACsearch dashboard or via:
curl -X POST https://your-aacsearch.example.com/api/connectors/shopify/sync/full \
  -H "Authorization: Bearer $AACSEARCH_CONNECTOR_TOKEN"

Field mapping

The Shopify product → AACsearch document mapping is implemented in packages/shopify-connector/src/product-mapper.ts. Highlights:

Shopify fieldAACsearch fieldNotes
idexternal_idNumeric Shopify product ID, stable
titletitleLocalized title for the configured market locale
body_htmldescriptionHTML stripped before send
vendorbrandEmpty string is dropped
product_type + tagscategoriesPlus collections that contain the product
tagstagsComma-split, trimmed
Variant skuskuFirst variant's SKU
Variant pricepriceLowest variant price across the product
Variant compare_at_pricesale_priceHighest "list" price across variants, when present
variants[].inventory_quantity sumstock_quantityAcross all locations
Inventory level > 0availabilityin_stock, out_of_stock, or preorder per variant policy
images[0].srcimage_urlFirst image; full image list lives in attributes.images
Variant optionsattributes.option_*Color, size, material as facetable fields
Locale (Shopify Markets)localeOne document per locale, suffixed external_id

Variant-level documents are not exported by default — Shopify products are sent as a single document with variant data flattened into attributes. If your storefront needs per-variant search, build a custom connector that emits one document per variant.

Webhook reliability

Shopify retries webhooks up to 19 times over 48 hours on non-2xx responses. The connector returns 200 as soon as the payload passes HMAC verification and is queued for processing — the actual call into the AACsearch Connector API runs asynchronously. If the AACsearch ingest queue is unavailable, the webhook handler logs the failure and a periodic reconciliation job will reissue the delta sync on the next scheduled run.

Failed HMAC verification returns 401 immediately — Shopify will mark the webhook as failed and back off. This is the desired behavior since a verification failure means the webhook was tampered with or the shared secret rotated without the connector being updated.

Troubleshooting

SymptomLikely causeFix
Webhooks not arrivingWrong webhook URL or HTTPS misconfiguredRe-register webhooks; verify the AACsearch host has a valid TLS cert
401 webhook_signature_mismatch in logsShopify webhook secret out of syncRotate the webhook secret in Shopify admin; update SHOPIFY_WEBHOOK_SECRET env var
Full sync hangs at 1000 productsConnector batch size hit; retry logic stuckCheck Shopify Admin API rate limit headers; lower batch size to 250
Products visible in Shopify, missing in searchProduct not published to the "Online Store" sales channelPublish the product to a sales channel the connector reads
Inventory shows 0 in search but in stockInventory location not whitelistedEnable the location in connector config or add read_locations scope
403 invalid_or_revoked_keyAACsearch connector token revoked or wrong organizationGenerate a new token in the AACsearch dashboard and update AACSEARCH_CONNECTOR_TOKEN

Roadmap

The current preview covers the OAuth flow, product/inventory webhooks, full and delta sync. Planned for the public listing release:

  • One-click install from the Shopify App Store
  • Per-market locale and currency UI in the embedded admin
  • Variant-level documents as an opt-in mapper
  • Bulk operations API for catalogs > 100k SKUs (instead of the REST batch loop)

Track the implementation under wiki/tasks/cms-platform-expansion.md § A12.

On this page