PhoenixKitEcommerce.Shopify.AdminClient (PhoenixKitEcommerce v0.5.1)

Copy Markdown View Source

Thin REST client for the Shopify Admin API's products.json endpoint.

Resolves the shop domain and access token from the PhoenixKit.Integrations connection identified by integration_uuid — never from application env (see PhoenixKitEcommerce.Shopify.Provider for why). Authenticates with the X-Shopify-Access-Token header, NOT Authorization: Bearer — that is what the REST Admin API expects for a Custom App's static token.

Summary

Functions

Fetches the product ids of collection_id, in the order Shopify returns them — Shopify applies the collection's own sort order to this endpoint, so no client-side sorting happens here; CollectionSync reads this order directly as item.position within the category. Paginated like fetch_products/2.

Fetches every collection from the connected store — custom_collections and smart_collections concatenated, each paginated like fetch_products/2. Each returned collection carries "kind" ("custom" or "smart", which endpoint it came from) and "position" — a running index across BOTH lists, in API order (custom first, then smart) — this is the order CollectionSync writes as category.position.

Fetches every product from the Shopify store connected via integration_uuid, following Link: rel="next" pagination.

Fetches the connected store's own shop.json — its name, domain, and crucially its currency. Per the per-domain-currency design (§7.5), a Shopify sync must be able to check the store's own currency against the base currency and refuse price updates on a mismatch rather than silently reimporting numbers that no longer mean what they used to.

Functions

fetch_collection_product_ids(collection_id, opts \\ [])

@spec fetch_collection_product_ids(String.t() | integer(), keyword()) ::
  {:ok, [term()]} | {:error, term()}

Fetches the product ids of collection_id, in the order Shopify returns them — Shopify applies the collection's own sort order to this endpoint, so no client-side sorting happens here; CollectionSync reads this order directly as item.position within the category. Paginated like fetch_products/2.

Options

Same as fetch_collections/1.

fetch_collections(opts \\ [])

@spec fetch_collections(keyword()) :: {:ok, [map()]} | {:error, term()}

Fetches every collection from the connected store — custom_collections and smart_collections concatenated, each paginated like fetch_products/2. Each returned collection carries "kind" ("custom" or "smart", which endpoint it came from) and "position" — a running index across BOTH lists, in API order (custom first, then smart) — this is the order CollectionSync writes as category.position.

Options

fetch_products(integration_uuid, opts \\ [])

@spec fetch_products(String.t(), keyword()) :: {:ok, [map()]} | {:error, term()}

Fetches every product from the Shopify store connected via integration_uuid, following Link: rel="next" pagination.

Options

  • :req_options — keyword list merged into Req.new/1 (e.g. plug: to stub the transport in tests).

fetch_shop(integration_uuid, opts \\ [])

@spec fetch_shop(String.t(), keyword()) :: {:ok, map()} | {:error, term()}

Fetches the connected store's own shop.json — its name, domain, and crucially its currency. Per the per-domain-currency design (§7.5), a Shopify sync must be able to check the store's own currency against the base currency and refuse price updates on a mismatch rather than silently reimporting numbers that no longer mean what they used to.

A single, unpaginated request — unlike fetch_products/2 and its siblings, there is only ever one shop.

Options