Skip to Content
🎉 探索 Shopify 的无限可能 结构化知识 + 实战案例,持续更新中...
进阶教程Shopify API 深度应用

Shopify Admin API 深度应用

Shopify Admin API 是 Shopify 后端能力对外暴露的核心入口。所有应用、ERP / WMS 同步、自动化集成最终都要走这套 API。本文聚焦在实战开发中真正影响项目成败的几个关键点:选型决策、限流机制、批量操作、版本管理。

不涉及基础调用入门——基础部分见 Shopify 官方 API 文档

一、GraphQL vs REST 选型

Shopify 2018 年起把 GraphQL 作为推荐方向,REST API 自 2024 年 10 月起进入维护模式(仅安全修复,不再新增功能)。新项目应优先使用 GraphQL。

关键差异

维度RESTGraphQL
数据获取多次请求拼装单次请求获取嵌套数据
接口稳定性字段固定客户端按需查询
限流计算每秒请求数(leaky bucket)查询成本(cost-based)
文档与示例历史积累丰富较新但完整
复杂查询需要多次往返一次往返
工具支持curl / Postman 友好GraphQL IDE 支持
Shopify 官方推荐不再推荐

何时仍可用 REST

  • 维护老代码且未在迁移计划中
  • 简单的单一资源 CRUD
  • 第三方库仅支持 REST

新功能 / 新接口(如 Cart API 部分)只在 GraphQL 提供。2025 年起的所有新项目都应优先 GraphQL

选型实例

获取 50 个产品 + 每个产品的图片 + 变体 + 库存:

  • REST:3-4 次请求(products + 每个产品的 images + variants + inventory levels)
  • GraphQL:1 次请求
query GetProductsWithDetails($first: Int!) { products(first: $first) { edges { node { id title handle descriptionHtml images(first: 10) { edges { node { url(transform: { maxWidth: 800 }) altText width height } } } variants(first: 100) { edges { node { id sku price inventoryQuantity selectedOptions { name value } } } } } } pageInfo { hasNextPage endCursor } } }

二、限流机制详解

Shopify API 限流是初学者最常踩的坑。两套 API 用不同的限流模型:

REST:Leaky Bucket

  • 每个店铺有”桶容量”40 请求(Plus 商家更高)
  • 桶以每秒 2 个请求的速度漏水
  • 请求填桶,桶满后 429 拒绝

应对

  • 监控 HTTP 响应 header X-Shopify-Shop-Api-Call-Limit(如 35/40
  • 接近 40 时延迟下次请求
  • 收到 429 后按响应 header Retry-After 等待
async function callShopifyRest(endpoint, options) { const response = await fetch(endpoint, options); const limit = response.headers.get('x-shopify-shop-api-call-limit'); const [current, max] = limit.split('/').map(Number); if (current > max * 0.8) { await sleep(500); } if (response.status === 429) { const retryAfter = parseInt(response.headers.get('retry-after') || '2'); await sleep(retryAfter * 1000); return callShopifyRest(endpoint, options); } return response.json(); }

GraphQL:Cost-Based

  • 每个店铺有”成本桶” 1000 点(Plus 更高)
  • 桶以每秒 50 点的速度恢复
  • 每个查询消耗一定点数(基础 1 点,连接字段按返回数量)

成本计算

query { products(first: 100) { # 成本 = 100(连接字段按 first 计算) edges { node { id # 0 variants(first: 10) { # 100 × 10 = 1000(嵌套连接乘法) edges { node { id price } } } } } } } # 总成本 ≈ 1100 点,单次查询即可超出桶容量

应对

  • 在响应 extensions.cost 中查看实际消耗
  • 减少 first 参数或拆多次查询
  • 用 fragment 但不要无限嵌套
const result = await graphqlClient.query({ query: PRODUCTS_QUERY }); console.log('Cost:', result.extensions.cost); // { // requestedQueryCost: 1100, // actualQueryCost: 250, // 实际成本基于返回数量 // throttleStatus: { // maximumAvailable: 1000, // currentlyAvailable: 750, // restoreRate: 50 // } // }

Bulk Operations(批量操作)

需要导出全店数据时不要用普通分页查询——会消耗大量配额。使用 GraphQL Bulk Operations:

mutation { bulkOperationRunQuery( query: """ { products { edges { node { id title variants { edges { node { id sku } } } } } } } """ ) { bulkOperation { id status } userErrors { field message } } }

特点:

  • 异步执行(提交后立即返回)
  • 完成后下载 JSONL 文件
  • 不消耗主限流配额
  • 适合全量导出(10万+ 产品的店铺)

每个店铺同时只能跑 1 个 Bulk Operation。

三、Webhook 集成

实时事件推送,避免轮询消耗 API 配额。

常用事件

事件用途
orders/create新订单 → 同步到 ERP
orders/updated订单变更 → 状态同步
orders/paid支付完成 → 触发履约
orders/fulfilled发货 → 通知客户
products/create / update产品同步
inventory_levels/update库存同步
customers/create新客户 → CRM 同步
customers/data_requestGDPR 请求
customers/redactGDPR 删除
shop/redact店铺卸载 App 后清理数据

注册 Webhook

mutation { webhookSubscriptionCreate( topic: ORDERS_CREATE webhookSubscription: { callbackUrl: "https://yourapp.com/webhooks/orders-create" format: JSON } ) { webhookSubscription { id } userErrors { field message } } }

验证 Webhook 签名

Shopify 在 HTTP header X-Shopify-Hmac-Sha256 提供签名。所有 Webhook 必须验签,否则接口可能被恶意伪造调用:

const crypto = require('crypto'); function verifyWebhook(rawBody, hmacHeader, secret) { const calculated = crypto .createHmac('sha256', secret) .update(rawBody, 'utf8') .digest('base64'); return crypto.timingSafeEqual( Buffer.from(calculated), Buffer.from(hmacHeader) ); } app.post('/webhooks/orders-create', (req, res) => { const hmac = req.headers['x-shopify-hmac-sha256']; const rawBody = req.rawBody; // 原始 body,未 JSON.parse if (!verifyWebhook(rawBody, hmac, SHOPIFY_WEBHOOK_SECRET)) { return res.status(401).send('Unauthorized'); } // 处理事件 res.status(200).send('OK'); });

Webhook 处理原则

  • 5 秒内响应 200:Shopify 等待时间上限 5 秒
  • 重试机制:超时或返回 5xx 时 Shopify 自动重试(最多 19 次,48 小时内)
  • 幂等性:同一事件可能被多次推送,处理函数必须幂等
  • 异步处理:复杂业务逻辑放队列异步处理,先 200 返回
app.post('/webhooks/orders-create', async (req, res) => { // 立即验签并响应 if (!verifyWebhook(...)) return res.status(401).send('Unauthorized'); // 入队,不阻塞响应 await queue.add('process-order', { body: req.body }); res.status(200).send('OK'); });

四、Access Token 管理

Token 类型

  • Public App Token:通过 OAuth 流程获取,给已安装店铺
  • Custom App Token:店主在后台创建,用于私有集成
  • Storefront API Token:用于面向公众的 Headless 站点

安全要点

  • 永远不要硬编码 token:用环境变量或密钥管理服务
  • 最小权限:只申请实际需要的 scope
  • 定期轮换:每 6-12 个月更换一次
  • 泄露应急:在 Shopify Partner 后台撤销并重新生成

Scopes 选择原则

Shopify 把权限拆得很细。常用:

Scope用途
read_products / write_products产品读写
read_orders / write_orders订单读写
read_customers / write_customers客户读写
read_inventory / write_inventory库存读写
read_fulfillments / write_fulfillments履约
read_locations多仓
read_price_rules / write_price_rules折扣规则

只申请必要的 scope——app review 阶段超出实际需要的 scope 会被 Shopify 退回审核。

五、API 版本管理

版本周期

Shopify 每季度发布新 API 版本,命名 YYYY-MM

  • 2024-01(1 月发布)
  • 2024-04(4 月发布)
  • 2024-07(7 月发布)
  • 2024-10(10 月发布)

每个版本支持 12 个月,过期后强制升级。未升级的应用会被自动迁移到下一个稳定版,可能触发 breaking change。

升级策略

调用版本指定

每次 API 调用都应该显式指定版本:

GET /admin/api/2024-10/products.json

GraphQL 同理:

POST /admin/api/2024-10/graphql.json

不要使用 unstable——它是开发预览,每周可能变更。

六、常见集成场景

场景 1:ERP 同步

ERP(NetSuite / 用友等) ↔ Shopify 订单方向: Shopify orders/create webhook → 服务器解析 → 推送到 ERP → 创建 ERP 订单 库存方向: ERP 库存变化 → 调 Shopify GraphQL mutation inventorySetOnHandQuantities → 同步到 Shopify

注意:

  • 双向同步必须有”事件来源”标记,避免无限循环
  • 网络异常时本地队列重试
  • 月度对账机制

场景 2:第三方仓库(3PL)集成

Shopify orders/paid → 推送到 3PL → 3PL 发货 → fulfillment 回写 Shopify

关键点:

  • 用 fulfillmentCreate mutation 完成发货
  • 物流追踪号回传:trackingInfo 字段
  • 部分发货支持(拆单)

场景 3:自定义 Checkout 后处理

orders/paid webhook → 异步处理:发优惠券、加会员积分、推送 CRM

不要在 Checkout 同步流程里做这些——会拖慢结账。

场景 4:客户数据导出(GDPR)

强制实现两个 Webhook:

  • customers/data_request:客户请求数据 → 30 天内提供
  • customers/redact:客户请求删除 → 30 天内删除

详见 GDPR 合规完整指南

七、性能与监控

客户端缓存

  • 不变数据(产品分类、店铺信息)本地缓存
  • 缓存失效靠 Webhook 触发(如 products/update)
  • 不要缓存订单或库存等高频变化数据

重试策略

  • 网络错误:指数退避(1s, 2s, 4s, 8s)
  • 429 限流:按 Retry-After 等待
  • 5xx 错误:最多 3 次重试

监控指标

  • API 调用次数 / 错误率 / 延迟(按 endpoint)
  • 限流命中次数
  • Webhook 接收延迟 / 失败率
  • Bulk Operation 完成时间

八、避免的常见错误

错误 1:在循环中调 API

// 反例:N+1 问题 for (const productId of productIds) { const product = await fetchProduct(productId); // 多次单独调用 } // 正确:批量查询 const products = await graphqlQuery(` query { nodes(ids: ${JSON.stringify(productIds)}) { ... } } `);

错误 2:硬编码 API 版本

// 反例:永远用 2022-01,无法升级 const url = 'https://shop.myshopify.com/admin/api/2022-01/products.json'; // 正确:版本变量化 const API_VERSION = process.env.SHOPIFY_API_VERSION || '2024-10'; const url = `https://shop.myshopify.com/admin/api/${API_VERSION}/products.json`;

错误 3:忽略 Webhook 重试

如果 Webhook 处理超过 5 秒,Shopify 会重试。如果处理函数不幂等,会重复处理订单。

错误 4:写权限申请过大

申请了 write_products 但只读产品。审核会被 Shopify 退回,且增加安全风险。

错误 5:不验签直接处理 Webhook

恶意第三方可以伪造 Webhook 攻击。所有 Webhook 必须验签

错误 6:缺少错误处理

// 反例 const data = await fetch(url).then(r => r.json()); // 正确 const response = await fetch(url); if (!response.ok) { const text = await response.text(); throw new Error(`Shopify API ${response.status}: ${text}`); } const data = await response.json(); if (data.errors) { throw new Error(`GraphQL errors: ${JSON.stringify(data.errors)}`); }

九、开发工具

必备工具

  • Shopify CLI:脚手架与本地开发
  • GraphiQL App:Shopify 自家的 GraphQL IDE
  • Postman 与 Shopify Postman Collection:REST 测试
  • Shopify Dev Console:API 调用日志查看

推荐工具

  • GraphQL Codegen:从 GraphQL Schema 自动生成 TypeScript 类型
  • @shopify/shopify-api:官方 Node.js SDK
  • @shopify/cli-hydrogen:Headless 项目脚手架

十、相关教程

最后更新时间: