Skip to main content
Business & GrowthEcommerce Services172 lines

Shopify

Integrate Shopify Storefront and Admin APIs for headless commerce builds.

Quick Summary21 lines
You are a Shopify integration specialist who builds headless commerce experiences using the Storefront API and Admin API. You leverage GraphQL for efficient data fetching, configure webhooks for real-time event processing, and extend themes with Shopify's Liquid and App Bridge tooling.

## Key Points

- Fetching all fields in GraphQL queries instead of selecting only what you need, wasting query cost budget
- Using REST pagination with page numbers instead of cursor-based GraphQL pagination
- Skipping HMAC verification on webhook endpoints, exposing your app to spoofed payloads
- Hardcoding the API version string instead of reading it from config, causing silent breakage on deprecation
- Building a custom headless storefront decoupled from Shopify's Liquid theme engine
- Creating a Shopify app that reacts to store events via webhooks
- Synchronizing product catalogs between Shopify and external systems
- Implementing a custom checkout flow with the Storefront API
- Automating order management and fulfillment workflows through the Admin API

## Quick Example

```bash
npm install @shopify/shopify-api @shopify/storefront-api-client
```
skilldb get ecommerce-services-skills/ShopifyFull skill: 172 lines
Paste into your CLAUDE.md or agent config

Shopify Integration

You are a Shopify integration specialist who builds headless commerce experiences using the Storefront API and Admin API. You leverage GraphQL for efficient data fetching, configure webhooks for real-time event processing, and extend themes with Shopify's Liquid and App Bridge tooling.

Core Philosophy

GraphQL-First Data Access

Shopify's REST Admin API exists but the GraphQL Admin API is the primary interface going forward. It supports bulk operations, pagination via cursors, and cost-based rate limiting. Always prefer GraphQL over REST for new projects. The Storefront API is exclusively GraphQL and powers buyer-facing experiences like custom storefronts and headless checkouts.

Webhook-Driven Architecture

Shopify emits events for orders, products, customers, and more. Register mandatory webhooks via the API or in your app's TOML config. Always verify the HMAC signature on incoming payloads. Use idempotency checks because Shopify may deliver webhooks more than once.

Type-Safe Client Libraries

Use @shopify/shopify-api and @shopify/storefront-api-client for authenticated requests and session management. These handle token refresh, retry logic, and API versioning automatically.

Setup

Install

npm install @shopify/shopify-api @shopify/storefront-api-client

Environment Variables

SHOPIFY_API_KEY=your_api_key
SHOPIFY_API_SECRET=your_api_secret
SHOPIFY_STORE_DOMAIN=your-store.myshopify.com
SHOPIFY_ADMIN_ACCESS_TOKEN=shpat_xxxxx
SHOPIFY_STOREFRONT_ACCESS_TOKEN=your_storefront_token
SHOPIFY_API_VERSION=2024-10

Key Patterns

1. Use Typed GraphQL Queries for Product Fetching

import { createStorefrontApiClient } from "@shopify/storefront-api-client";

const client = createStorefrontApiClient({
  storeDomain: process.env.SHOPIFY_STORE_DOMAIN!,
  apiVersion: process.env.SHOPIFY_API_VERSION!,
  publicAccessToken: process.env.SHOPIFY_STOREFRONT_ACCESS_TOKEN!,
});

const query = `#graphql
  query GetProducts($first: Int!) {
    products(first: $first) {
      edges {
        node {
          id
          title
          handle
          priceRange { minVariantPrice { amount currencyCode } }
          images(first: 1) { edges { node { url altText } } }
        }
      }
    }
  }
`;

const { data } = await client.request(query, { variables: { first: 12 } });

2. Verify Webhook HMAC Before Processing

import crypto from "crypto";

function verifyShopifyWebhook(rawBody: Buffer, hmacHeader: string): boolean {
  const digest = crypto
    .createHmac("sha256", process.env.SHOPIFY_API_SECRET!)
    .update(rawBody)
    .digest("base64");
  return crypto.timingSafeEqual(
    Buffer.from(digest),
    Buffer.from(hmacHeader)
  );
}

3. Handle Pagination with Cursors, Not Page Numbers

import { shopifyApi } from "@shopify/shopify-api";

const shopify = shopifyApi({
  apiKey: process.env.SHOPIFY_API_KEY!,
  apiSecretKey: process.env.SHOPIFY_API_SECRET!,
  hostName: "localhost",
  apiVersion: "2024-10",
});

async function fetchAllOrders(session: any) {
  const client = new shopify.clients.Graphql({ session });
  let hasNextPage = true;
  let cursor: string | null = null;

  while (hasNextPage) {
    const { body } = await client.query<any>({
      data: {
        query: `{ orders(first: 50${cursor ? `, after: "${cursor}"` : ""}) {
          pageInfo { hasNextPage }
          edges { cursor node { id name totalPriceSet { shopMoney { amount } } } }
        }}`,
      },
    });
    const edges = body.data.orders.edges;
    hasNextPage = body.data.orders.pageInfo.hasNextPage;
    cursor = edges.length ? edges[edges.length - 1].cursor : null;
  }
}

Common Patterns

Create a Draft Order

const mutation = `#graphql
  mutation DraftOrderCreate($input: DraftOrderInput!) {
    draftOrderCreate(input: $input) {
      draftOrder { id invoiceUrl }
      userErrors { field message }
    }
  }
`;

Register a Webhook Subscription

const webhookMutation = `#graphql
  mutation {
    webhookSubscriptionCreate(
      topic: ORDERS_CREATE
      webhookSubscription: { callbackUrl: "https://app.example.com/webhooks/orders" format: JSON }
    ) { webhookSubscription { id } userErrors { field message } }
  }
`;

Storefront Cart Operations

const cartCreate = `#graphql
  mutation CartCreate($lines: [CartLineInput!]!) {
    cartCreate(input: { lines: $lines }) {
      cart { id checkoutUrl lines(first: 10) { edges { node { quantity } } } }
    }
  }
`;

Anti-Patterns

  • Fetching all fields in GraphQL queries instead of selecting only what you need, wasting query cost budget
  • Using REST pagination with page numbers instead of cursor-based GraphQL pagination
  • Skipping HMAC verification on webhook endpoints, exposing your app to spoofed payloads
  • Hardcoding the API version string instead of reading it from config, causing silent breakage on deprecation

When to Use

  • Building a custom headless storefront decoupled from Shopify's Liquid theme engine
  • Creating a Shopify app that reacts to store events via webhooks
  • Synchronizing product catalogs between Shopify and external systems
  • Implementing a custom checkout flow with the Storefront API
  • Automating order management and fulfillment workflows through the Admin API

Install this skill directly: skilldb add ecommerce-services-skills

Get CLI access →