EN
Shopify 知识库 · 概念

Webhooks:订阅、校验与重试

说明 Shopify Webhooks 的订阅方式(应用配置文件与 Admin API)、投递目标、请求头与 HMAC 校验、响应时限与重试、去重与对账、强制合规 webhook,并区分它与前台 Web Pixels 事件、Flow 自动化以及开发者预览中的 Events。

Webhook 是 Shopify 在店铺里发生事件后主动通知应用服务器的机制,官方称其为“持续轮询店铺数据的高性能替代”。它解决的是“应用要及时知道订单、商品、客户等发生了变化”;不解决顾客在浏览器里的行为采集,也不保证每条事件必达。Webhooks 概览

本库哪些内容依赖它

  • Admin GraphQL API:webhook 告诉应用“有变化”,拉取详情与对账用 Admin API;
  • OAuth 回调指南:HMAC 校验的思路相同,但回调与 webhook 是两条链路、校验对象不同;
  • 两个 App 共用后端:验签必须用接收该请求的 App 的 secret,app/uninstalled 与 shop/redact 的处理边界在那里;
  • App Review 准备:三个强制合规 webhook 的验收;
  • 环境隔离:各环境的 webhook 入口应指向各自环境;
  • 隐私与同意:商家在后台处理顾客数据请求,与应用侧合规 webhook 是同一件事的两端;
  • Web Pixels、Flow:分工见下文。

本文是 webhook 机制的权威来源,其他文章只写各自页面语境下的用法。

核心对象与概念

对象含义备注
Topic事件类型,如 products/create、orders/create参考页给出的示例;topic 总数官方页未写明
应用级订阅(app-specific)在 shopify.app.toml 声明,对所有安装该应用的店铺一律生效随应用部署生效
店铺级订阅(shop-specific)经 Admin API 的 webhookSubscriptionCreate 创建,每店可不同用 webhookSubscriptions 查询管理
投递目标HTTPS 地址、Amazon EventBridge ARN、Google Cloud Pub/Sub URIPub/Sub 格式 pubsub://{project-id}:{topic-id}
api_version决定载荷的序列化版本,配置在 [webhooks]官方建议每季度更新到最新稳定版
合规 topiccustomers/data_request、customers/redact、shop/redact见下文
Events下一代订阅机制,支持字段级触发与自定义 GraphQL 载荷开发者预览,见下文

在哪里配置

  • 应用级:shopify.app.toml 中的 [[webhooks.subscriptions]]。必填 topics 与 uri;可选 include_fields(限定载荷字段)、filter(过滤表达式,用于控制是否投递)、name(字母数字、-、_,最长 50 字符)、compliance_topics。写入 [webhooks] api_version 后部署生效。已部署订阅可在 Dev Dashboard 的 Versions > Configuration 中查看。
  • 店铺级:Admin API 的 webhookSubscriptionCreate,以及 webhookSubscriptions 查询。
  • 最小配置形态(官方页给出的示例形态,域名为虚构):
[webhooks]
api_version = "2026-07"

[[webhooks.subscriptions]]
topics = ["products/create"]
uri = "https://your-app.example.com/webhooks/products"

与主题、Liquid 和 API 的连接

  • 与 Liquid 无关。 Webhook 是服务端到服务端的通知,不在店面运行,也不出现在主题里。
  • 载荷形状。 投递体是所订阅 topic 的完整 REST 资源的 JSON;即使 Admin API 以 GraphQL 为主(见Admin GraphQL API),webhook 载荷仍是 REST 形。需要 GraphQL 载荷与字段级触发时看 Events。
  • 请求头。 每次投递携带下表头(Delivery structure):
请求头含义
X-Shopify-Topictopic 名,如 products/update
X-Shopify-Hmac-Sha256Base64 编码的 HMAC 签名,仅 HTTPS 投递
X-Shopify-Shop-Domain触发事件的 myshopify.com 域名
X-Shopify-API-Version序列化载荷所用的 API 版本
X-Shopify-Webhook-Id每次投递唯一的复合键,用于识别与去重单次投递
X-Shopify-Triggered-AtShopify 触发该投递的时间戳
X-Shopify-Event-Id同一商家动作产生的所有投递共享的 ID
X-Shopify-Name开发者在 name 字段给订阅起的名字(可选)

限制、数值与易错点

核验于 2026-09-29,逐条标来源;数值会变,使用前重读来源页。

  1. 响应要快,且只有 2xx 算成功。 官方写明 Shopify 的连接超时为 1 秒,整个请求超时为 5 秒;用 200 OK 确认收到,200 范围之外(包括 3xx)都算错误。所以处理器应先验签、落队列、立刻返回,再异步处理。HTTPS 投递
  2. 重试与自动删除。 无响应或错误时,Shopify 在之后 4 小时内重试 8 次;连续 8 次失败后,经 Admin API 创建的订阅会被自动删除。订阅页写明应用级订阅失败时不会被 Shopify 删除,店铺级会被删除。管理订阅。EventBridge 与 Pub/Sub 的重试策略两页均未读到,未核验。
  3. HMAC 校验步骤。 取 X-Shopify-Hmac-Sha256 头;对原始请求体用应用的 client secret 计算 HMAC-SHA256;用 Base64 解码后的值做恒定时间比较;不一致就拒绝。官方特别写明:若在验签前用 express.json() 之类中间件解析了正文,就无法得到原始字节,验签中间件必须放在任何正文解析之前。若轮换 client secret,用新密钥生成摘要可能最长需要一小时生效,轮换后一小时内出现验签不一致时,先排除这一因素。验证投递
  4. 投递不保证必达,也不保证顺序。 官方写明 webhook 投递并不总是有保证,应用可能因处理器故障或停机而漏掉事件;Shopify 不保证同一 topic 内或跨 topic 的顺序。建议做对账任务,定期用 updated_at 过滤从 API 拉取;排序用 X-Shopify-Triggered-At 或载荷里的 updated_at。最佳实践
  5. 去重用哪个头。 最佳实践页写用 X-Shopify-Webhook-Id 来忽略重复投递;Delivery structure 页把它描述为每次投递唯一的复合键,把 X-Shopify-Event-Id 描述为同一商家动作的所有投递共享的 ID。Event-Id 由同一动作的所有投递共享,所以它相同并不表示是重复投递,不能单独作去重键。Webhook-Id 在重试时是否不变,官方页未写明,未核验;落地前先在测试店对失败重试做一次观察,再决定去重键。
  6. 强制合规 webhook。 通过 Shopify App Store 分发的应用必须订阅三个 topic:customers/data_request(顾客向店主请求其数据)、customers/redact(店主请求删除某顾客的数据)、shop/redact(店主卸载应用 48 小时后发送)。要求以 2xx 确认,并在收到请求后 30 天内完成对应动作;配置为 compliance_topics = ["customers/data_request", "customers/redact", "shop/redact"];未提供或未按要求响应,审核会被拒。官方页表述的适用范围是 App Store 分发的应用;自定义分发与其他类型是否也必须订阅,该页未写,法规义务另需合规确认。隐私合规。webhook 参考页也写明:通过 App Store 分发的应用必须订阅这些强制 topic。
  7. 订阅的作用域。 应用级订阅对每个安装的店铺一视同仁;店铺间需要不同订阅时,只能用店铺级。同一 topic 同时存在两种订阅时是否会重复投递,官方页未写,未核验,去重逻辑不要假定不会。
  8. Events 仍在预览。 官方写明 Events 处于 unstable API 版本的开发者预览,只覆盖部分 topic,“测试可用,生产继续用 webhook”;它支持字段级 triggers、query_filter 与自定义 GraphQL 载荷,只能在 shopify.app.toml 配置;Events 与 webhook 可以在同一份配置里并存。Events 与 webhooks 对比

与 Web Pixels 和 Flow 的分工

机制运行位置触发适合
WebhookShopify 到应用服务器店铺数据变化(订单、商品、客户等)服务端同步、通知、合规响应
Web Pixels顾客浏览器的沙箱(App Pixel 为 strict,Custom Pixel 为 lax)顾客行为事件前台采集,见 Web Pixels
FlowShopify 后台自动化触发器(含订单、库存、客户等)无需自建服务的后台自动化,见 Flow

三者不是同一条数据链路:webhook 不会替代 Pixel 的浏览器事件(顾客是否同意、页面是否加载都不在其中),Pixel 也拿不到只发生在后台的变化(如手动调整库存)。购买事件的验证见购买与事件验证,部署方式比较见标签与网关。Flow 中 HTTP 请求动作的行为本库尚未核验,本文不下结论。

验证一次

  1. 在开发店部署一个应用级订阅,触发一次对应事件,核对 X-Shopify-Topic、X-Shopify-Shop-Domain、X-Shopify-API-Version 与配置的 api_version 一致;
  2. 用错误密钥、被解析过的正文各发一次请求,确认验签都会失败,只有原始字节加正确 secret 才通过;
  3. 让处理器故意返回 500 或超过 5 秒,观察重试次数、间隔,并记录重试请求里 X-Shopify-Webhook-Id 与 X-Shopify-Event-Id 是否变化(决定去重键);
  4. 乱序与漏投用对账验证:停掉接收端一段时间后恢复,确认对账任务能按 updated_at 补齐;
  5. 三个合规 topic 各触发一次(触发或模拟方式官方页未读,未核验),确认 2xx 响应且删除动作可追溯;卸载后 48 小时的 shop/redact 需另行跟踪。

待继续完善

  • delivery filtering 的 filter 表达式语法与限制;
  • EventBridge、Pub/Sub 的投递、重试与权限配置;
  • 各 topic 的载荷字段与版本差异;
  • Events 进入正式版后的 topic 覆盖与迁移路径。