概要
Webhook は、ストアで何かが起きたことを Shopify がアプリに知らせてくれる仕組みです。「注文が入った」「商品が更新された」「アプリがアンインストールされた」といった出来事を、アプリ側から定期的に問い合わせに行かなくても受け取れます。
非エンジニア向けに言い換えると、「Shopifyからの通知メール」に近いものです。ただし宛先はアプリのサーバーで、内容はデータです。定期的にAPIを叩いて変化を探す(ポーリング)よりも速く、Shopify側の負荷も小さくて済みます。
ここで最も重要なのは、Shopifyはこの通知が必ず届くことを保証していないという点です。公式ドキュメントに「アプリはWebhookからデータを受け取れることを前提にしてはいけない」と明記されています。この一文が、Webhookまわりの設計・見積もり・障害対応のすべての前提になります。
出典: About webhooks
何ができるか
Webhookで受け取ったイベントをきっかけに、以下のような処理を組めます。Shopifyが公式に挙げている用途を含みます。
やりたいこと |
使うイベントの例 |
業務課題の例 |
|---|---|---|
受注データを外部システムへ連携 |
orders/create |
注文が入ったら基幹システム・会計ソフトへ自動で流し込み、手入力をなくす |
在庫の変化を関係者へ通知 |
inventory_levels/update |
在庫が閾値を割ったら倉庫担当へ通知し、欠品を未然に防ぐ |
配送業者への情報連携 |
orders/updated、refunds/create |
注文変更・返品・返金の発生を配送業者に伝え、誤配送を防ぐ |
商品情報の同期 |
products/update |
本体価格が変わったら関連する保証商品の価格も自動で追随させる |
アンインストール時のデータ削除 |
app/uninstalled、shop/redact |
解約したストアのデータを自社DBから確実に消す(審査要件でもある) |
出典: About webhooks / Webhooks reference
登録方法は2種類あり、挙動が大きく違う
Webhookの購読(サブスクリプション)には2つの方式があり、障害時の挙動がまったく異なります。ここは実務で非常に効いてきます。
アプリ単位(app-specific) |
ストア単位(shop-specific) |
|
|---|---|---|
設定場所 |
設定ファイル( |
GraphQL Admin API |
適用範囲 |
インストール済みの全ストアに一律 |
ストアごとに違う設定にできる |
連続失敗したとき |
Shopifyに削除されない |
Shopifyに自動削除される |
障害復旧後の再登録 |
不要 |
必要(コードで作り直す) |
対応トピック |
product_feeds系の3トピックを除く全て |
全トピック |
Shopifyはアプリ単位を推奨しています。理由は上表の「連続失敗したときに削除されない」点です。ストア単位で登録していると、自社サーバーが数時間落ちただけで、Shopify側から購読を勝手に消されることがあります。この場合、サーバーが復旧してもWebhookは二度と届きません。「サーバーは直ったのに、なぜか特定のストアだけデータが来なくなった」という障害は、たいていこれが原因です。
なお、Shopify管理画面から作るカスタムアプリはCLIやTOMLファイルを使えないため、必然的にGraphQL Admin API経由(ストア単位)での登録になります。カスタムアプリ案件では、この削除リスクを織り込んだ運用設計が必要です。
ストア単位からアプリ単位へ移行する場合は、先に既存の購読を削除しないと同じ通知が二重に届きます。
出典: Manage webhook subscriptions
配信先は3種類から選べる
配信先 |
特徴 |
|---|---|
Google Cloud Pub/Sub |
Shopify推奨。受信の取りこぼしやバースト対策をクラウド側が引き受ける |
Amazon EventBridge |
同上。AWS構成の場合はこちら |
HTTPS(自社サーバー) |
自前で受信基盤を作る方式。後述の追加要件がすべて自己責任になる |
Pub/Sub や EventBridge を使うと、署名検証(HMAC)が不要になり、5秒以内の応答やバースト対策もクラウド側のキューが吸収してくれます。自社でHTTPSエンドポイントを立てる構成は、一見シンプルに見えて運用負荷が高い選択です。
出典: Manage webhook subscriptions / Verify webhook deliveries
受け取る量を減らす仕組み
何もしないと、購読したトピックの全イベントが全データ付きで届きます。これを絞る手段が2つあります。
filter — 条件に合わないイベントは配信そのものを止めます。たとえば variants.price:>=10.00 と書けば、10ドル以上のバリアントを含む商品更新だけが届きます。2024-07 APIバージョン以降で利用可能です。
include_fields — 届くデータの項目を絞ります。["id", "variants.price"] のように指定すれば、巨大な商品データではなくIDと価格だけが届きます。通信量とサーバー負荷が下がります。
両方使う場合、filterで参照する項目はinclude_fieldsにも必ず含める必要があります。
ここには落とし穴が3つあります。
filterに存在しない項目名を書くと、購読は作成できてしまうのに配信が全部止まります。エラーにならないため気づきにくく、「なぜかWebhookが1件も来ない」という調査の難しい障害になります。構文自体が誤っている場合は購読作成が失敗するので、むしろ気づけます。
filterは大文字小文字を区別し、完全一致で判定します。Shopifyの検索窓の挙動(あいまい検索・大文字小文字を無視)とは違います。
include_fieldsで項目を絞りすぎると、Shopifyが同一内容の連続配信を間引きます(デバウンス)。たとえばIDと商品名だけに絞ると、価格を2回続けて変えても2回目が届きません。これを防ぐには、毎回値が変わる
updated_atを含めておきます。
また、metaobjectsの3トピック(作成・更新・削除)はfilterの指定が必須です。type:* のようなワイルドカードは使えず、対象のタイプを個別に列挙する必要があります。
出典: Filter webhook deliveries / Webhooks delivery structure
信頼性について保証されていること・されていないこと
ここが本日の中心です。Shopifyが保証していない事項を正確に把握しておくことが、提案・見積もり・障害説明のすべての土台になります。
項目 |
Shopifyの保証 |
アプリ側が取るべき対策 |
|---|---|---|
必ず届くか |
保証しない |
定期的にAPIで差分を取り直す照合処理(reconciliation)を必ず作る |
順番どおり届くか |
保証しない。同一トピック内でも、同じ商品に対する複数トピック間でも順不同 |
ヘッダーの X-Shopify-Triggered-At や本文の updated_at で時系列を判断する |
1回だけ届くか |
保証しない。重複は最小化するが起こりうる |
何度実行しても同じ結果になる処理にする。または X-Shopify-Webhook-Id で重複を検知して捨てる |
すぐ届くか |
保証しない。最大で1日遅れる可能性が公式に言及されている |
遅延が業務上問題になるなら、受信時刻と発生時刻を比較して判断する |
実際に起こりうる例として、Shopifyは「products/update が products/create より先に届くことがある」と明記しています。「作成された順に処理すれば大丈夫」という前提のプログラムは壊れます。
照合処理については、Shopifyは「多くのGraphQLクエリが updated_at での絞り込みに対応しているので、前回実行時以降に更新されたものを取り直すジョブを作る」ことを推奨しています。アプリのUIに「同期」ボタンを置いて手動再取得できるようにする方法も公式に挙げられています。
出典: About webhooks / Verify webhook deliveries
受信側に課される制約(HTTPS配信の場合)
項目 |
制約 |
実務上の意味 |
|---|---|---|
接続タイムアウト |
1秒 |
接続確立が遅いだけで失敗扱いになる |
全体タイムアウト |
5秒 |
重い処理を同期でやると必ず失敗する |
成功とみなす応答 |
200番台のみ |
3XX(リダイレクト)もエラー扱い。URL変更時の転送設定は事故のもと |
SSL証明書 |
Shopify側で検証される |
証明書の期限切れで全Webhookが止まる |
Keep-Alive |
有効化を推奨 |
同時大量配信時のオーバーヘッド削減 |
5秒ルールへの対策は「受け取ってすぐ200を返し、処理は後回しにする」のが定石です。Shopifyもキューを使って非同期処理することを公式に推奨しています。セール時など注文が集中する場面では、この設計をしていないと連鎖的に失敗します。
Dev Dashboardの監視画面では、応答時間が4〜5秒に張り付いている場合は要注意サインとして扱うよう案内されています。
出典: Verify webhook deliveries / Troubleshoot webhooks
失敗したときの挙動
応答がない、またはエラーが返ると、Shopifyは4時間のあいだに最大8回リトライします。リトライの間隔は失敗のたびに広がっていきます。
8回連続で失敗すると、ストア単位で登録した購読は自動削除されます。同時に、アプリの緊急連絡先メールアドレスへ警告メールが送られます。アプリ単位で登録していれば削除はされません。
Dev Dashboardの監視画面で見るべき指標は以下です。
指標 |
意味・判断基準 |
|---|---|
失敗率 |
0.5%を超えたら異常。平均より高い水準とされる |
削除された購読数 |
該当ストアにはもうデータが届いていない。修正後に再登録が必要 |
応答時間 |
90パーセンタイル値。4〜5秒ならタイムアウト寸前 |
特定トピックだけ失敗率が高い |
そのトピック固有の処理か、特定ストアのデータに問題がある |
全トピックで失敗率が高い |
自社サーバー側の障害を疑う |
ログと監視データは過去7日分しか保持されず、リアルタイム更新ではなく数分の遅延があります。長期の障害分析には自社側のログが必要です。
なりすまし対策(HMAC検証)
HTTPS配信の場合、受け取ったデータが本当にShopifyから来たものかを必ず検証する必要があります。検証せずに処理すると、第三者が偽の注文データを送り込めてしまいます。
各配信には
X-Shopify-Hmac-Sha256ヘッダーに署名が付いてくるアプリのクライアントシークレットとリクエストの生データから署名を計算し、一致するか比べる
Pub/Sub と EventBridge 経由ではHMAC検証は不要
よくある失敗は、JSONパーサーが先に動いてしまい、生データが手に入らず検証に失敗するというものです。Shopifyもこの点を公式に注意喚起しています。
また、クライアントシークレットを更新(ローテーション)した場合、新しいシークレットでの署名生成に切り替わるまで最大1時間かかります。切り替え作業のタイミングでは、この移行期間を考慮する必要があります。
重複を見分けるためのヘッダー
ヘッダー |
役割 |
|---|---|
X-Shopify-Webhook-Id |
1回の配信ごとに固有。重複配信の検知はこれを使う |
X-Shopify-Event-Id |
同じマーチャント操作から生まれた配信で共通。同一操作の紐付けに使う |
X-Shopify-Triggered-At |
Shopifyが配信を発生させた時刻。順序の判断に使う |
X-Shopify-Topic |
どのイベントか(例: products/update) |
X-Shopify-Shop-Domain |
どのストアからか |
X-Shopify-API-Version |
どのAPIバージョンでデータが作られたか |
同じトピックに複数の購読を登録している場合、購読の数だけ配信が来ます。それぞれ Webhook-Id は違いますが Event-Id は同じになります。
出典: Webhooks delivery structure
App Store公開に必須のコンプライアンスWebhook
App Storeで配布する公開アプリは、個人データを一切扱っていなくても、以下3つのWebhookへの対応が必須です。未対応だと審査で落とされます。
トピック |
内容 |
対応期限・タイミング |
|---|---|---|
customers/data_request |
顧客が自分のデータの開示を請求した |
受信から30日以内にストアオーナーへ直接提供 |
customers/redact |
顧客データの削除請求 |
受信から30日以内。直近6ヶ月に注文がない顧客は請求から10日後に通知が来る。注文がある場合は6ヶ月経過まで通知が保留される |
shop/redact |
ストアのデータ削除 |
アンインストールから48時間後に通知が来る |
審査で確認される要件として、HMACヘッダーが不正な場合は 401 Unauthorized を返さなければならないという明確な規定があります。単に200を返すだけの実装では通りません。
なお、これらのコンプライアンストピックはアプリ単位(設定ファイル)でのみ登録でき、Admin API からは登録できません。
法的にデータ保持義務がある場合は削除しなくてよい、という例外も明記されています。
Events(次世代の仕組み)— 現時点では本番利用不可
Shopifyは Webhook の後継として Events を開発者プレビューとして提供しています。将来的にはこちらが主流になると公式に明言されています。
Webhooks(現行) |
Events(次世代) |
|
|---|---|---|
対応範囲 |
Shopifyの全リソース |
一部トピックのみ |
APIバージョン |
安定版 |
unstable のみ |
登録方法 |
設定ファイル または Admin API |
設定ファイルのみ |
絞り込みの粒度 |
項目の値による絞り込み |
「価格が変わったときだけ」のような項目単位の指定が可能 |
受け取るデータの形 |
固定(REST形式の全項目) |
自分でGraphQLクエリを書いて設計できる |
Eventsの価値を業務目線で言うと、**「無駄な通知を受け取らなくて済む」**ことです。現行のWebhookでは「商品が更新された」としか分からないため、アプリ側で前回の値と比較して「今回は価格が変わったのか、説明文が変わったのか」を判定する処理が必要でした。Eventsでは「価格が変わったときだけ通知して」と指定できます。
現時点での判断としては、本番はWebhook、Eventsは検証のみです。Shopifyも「本番ではWebhookを使うこと」と明記しています。両者は同じ設定ファイルに共存できるため、トピック単位で少しずつ移行していく形になります。
出典: Events and webhooks / Events reference
できないこと・注意点のまとめ
確実な配信は保証されていません。照合処理の実装は選択肢ではなく必須です。見積もりに必ず含めます。
順序は保証されていません。更新通知が作成通知より先に来ることがあります。
重複が起こりえます。同じ処理を2回受けても壊れない作りにする必要があります。
最大1日の遅延がありえます。「Webhookで即時連携します」という説明は不正確です。
応答は5秒以内。重い処理を同期で書くと必ず失敗します。
3XXリダイレクトは失敗扱いです。エンドポイントURLを変える際は注意が必要です。
ストア単位の購読は8回連続失敗で自動削除されます。サーバー障害がデータ欠損に直結します。
filterに存在しない項目名を書くと全配信が停止します。エラーが出ないため発見が遅れます。
include_fieldsで絞りすぎると同一内容の配信が間引かれます。updated_atを含めるのが定石です。
ログは7日分のみです。長期の分析には自社ログが必要です。
Eventsはまだ本番利用できません。unstableバージョン限定です。
コンプライアンスWebhookは公開アプリの必須要件で、Admin APIからは登録できません。
この機能で解決できる業務課題
手作業の受注転記をなくす — 注文発生を検知して基幹・会計・配送システムへ自動連携し、転記ミスと工数を削減できる
在庫欠品の予防 — 在庫変動を即座に検知して担当者へ通知でき、売り逃しと過剰発注を減らせる
API呼び出し回数の削減 — 変化を探すために定期的にAPIを叩く必要がなくなり、レート制限に当たりにくくなる
解約時のデータ削除の確実な実行 — 法令対応と審査要件を同時に満たせる
障害の説明責任を果たせる — 「なぜデータが欠けたのか」をプラットフォームの仕様として説明でき、照合処理という具体的な再発防止策を提示できる
提案段階での期待値調整 — 「リアルタイム連携」を安易に約束せず、遅延・重複・欠損がありうる前提で要件を握れる
前回(2026-07-29)からの変更点
changelog を再確認しましたが、7月24日以降に新規の追加項目はありません。最新は変わらず 07.24 の「無効なメタフィールドクエリがエラーを返すようになる(2026-10以降)」です。
本日のテーマに直接関係する直近の変更は、**7月21日の「Events でメタフィールドトリガーと対応トピックが追加された」**です。内容は以下のとおりです。
Events で購読できるトピックに
Order、Collection、InventoryItem、InventoryShipment、Locationが追加されたProduct、Order、Customer、Collection、Locationのメタフィールドの変化を直接検知できるようになった(ProductVariant のメタフィールドは Product トピック経由)$appメタフィールドと通常のメタフィールドの両方に対応。ただしアクセス権のないメタフィールドは購読できない
これは「商品が更新された通知を全部受け取って、アプリ側で前回値と比較する」という現行の非効率なやり方を不要にする変更で、Eventsが実用に近づいている兆候として押さえておく価値があります。ただし依然として unstable 限定であり、本番投入はできません。
もう一つの流れとして、5月27日に Events が開発者プレビュー入りしてから、7月21日に対応トピックが拡張されるまで約2ヶ月です。この拡張ペースが続けば、来年前半には安定版化とWebhookからの移行案内が出る可能性があります。既存アプリの保守契約を議論する際の材料になります。
出典: Developer changelog / Metafield triggers and additional topics are now available for Events
次回以降に整理する予定のテーマ
認証とアクセススコープ(OAuth・Token Exchange・セッショントークン) / Agents(shopify.dev/docs/agents) / Checkout拡張の制約 / Metafields・Metaobjects のデータモデル / App Store 審査要件と課金(App Pricing移行) / Flow・POS・Customer accounts の拡張ポイント / App Events(アプリの利用状況データ)
未確認事項
「最大1日遅延しうる」という記述はありますが、実際の遅延分布や、どのような状況で大幅な遅延が起きるのかは公開されていません
リトライ間隔の具体的な計算式(4時間で8回の配分)は公開されていません
ストア単位購読の自動削除について、「8回連続失敗」と「24時間以内の複数回失敗」という2つの表現がドキュメント内に混在しており、正確な削除条件は要確認です
デバウンス(同一内容の配信の間引き)が働く「短い時間枠」の具体的な長さは公開されていません
Webhookペイロードのサイズ上限は明示されていません。Dev Dashboardで実配信のサイズは確認できます
Events の安定版リリース時期は公表されていません
Agents(shopify.dev/docs/agents)のリファレンスは本日も未着手です

