WooCommerce の Webhook 配信の仕組み

配信は Action Scheduler と WP-Cron 経由なので、ページの読み込みを待ってから送られます。連続して 5 回を超えて失敗すると、Webhook は無効化されます。署名形式と Node 検証コードを載せています。

配信の挙動

プロバイダーの公式ドキュメントから読み取っています(最終確認 2026-08-06)。プロバイダーが数値を示していない項目には、この表も数値を載せていません。

応答期限プロバイダーは未公表

配信は Action Scheduler のキューに入り、WP-Cron で処理される。そのため送信はイベント発生時ではなく、次にページが読み込まれたときになる

リトライプロバイダーは未公表
打ち切り配信が 5 回を超えて連続で失敗すると Webhook が無効化される
出典https://woocommerce.com/document/webhooks/

署名

ドキュメントを読んだだけではなく、テストスイートで裏付けた動作する検証コードで確認しています。最終検証日は 2026-08-20 です。

アルゴリズムHMAC-SHA256
署名対象raw body
エンコードbase64
ヘッダーx-wc-webhook-signature
許容範囲適用なし

検証する

JSON としてパースする前の生のリクエストボディを、バイト単位でそのまま使います。フレームワークがペイロードを再シリアライズした時点で、このページのどの方式も検証に失敗します。

const crypto = require("node:crypto");

// base64(HMAC-SHA256(secret, raw body))
const expected = crypto
  .createHmac("sha256", webhookSecret)
  .update(rawBody)
  .digest("base64");
const received = Buffer.from(req.headers["x-wc-webhook-signature"] ?? "");
const wanted = Buffer.from(expected);
// timingSafeEqual throws on a length mismatch, so check that first.
const valid =
  received.length === wanted.length && crypto.timingSafeEqual(received, wanted);

落とし穴

Webhook は注文が発生した時点では発火しません。配信は Action Scheduler のキューに入り、Action Scheduler は WP-Cron で動き、WP-Cron は誰かが次にページを読み込んだときに動きます。アクセスの少ないストアでは、最初のバイトが送られるまでに数分の遅れが組み込まれていることになります。

配信が 5 回を超えて連続で失敗すると、Webhook は完全に無効化されます。下流の何かが目に見えて古くなるまで、ストアのオーナーが気づくことはまずありません。

あわせて読む

AnyHook は、WooCommerce から受信するエンドポイントの手前に入ります。約 1 秒で応答し、サーバーがダウンしていれば独自のスケジュールでリトライします。すべてのイベントは再送できる状態で保存されます。 変えるのは URL 1 つだけで、コードはそのままです。

仕組みを見る →