すべての記事
電子商取引の注文および製品イベントが WordPress ストアを出て、署名されたトンネルを通過してローカルホスト Webhook ハンドラーに到達します。
WooCommerceWordPresse-commerce webhookslocalhost

Localhost で WooCommerce Webhook をテストする

ローカルホストで WooCommerce Webhook をテストするには、HTTPS トンネルを使用してローカル ハンドラーを公開し、WooCommerce → 設定 → 詳細 → Webhook で Webhook を作成し、確認します。 X-WC-Webhook-Signature 生の本体の Base64 HMAC-SHA256 ダイジェストとして。 安全なテストストアで注文または製品の変更をトリガーし、配送を検査し、レシーバーを展開せずに繰り返します。

WooCommerce がいつ何を送信するか

WooCommerce は、注文、商品、クーポン、または顧客が作成、更新、または削除されたときに配信 URL を通知できます。拡張機能ではトピックを追加でき、開発者はカスタム トピックを定義できます。構成された各 Webhook には、名前、ステータス、トピック、配信 URL、シークレット、および API バージョンがあります。の WooCommerce Webhook の公式ドキュメント 作成、トピック、配信ログ、および失敗の動作について説明します。

Webhook は、すべてのストアのミューテーションに自動的に接続されるのではなく、トピックに接続されます。統合に必要な最も狭いトピックを選択してください。注文によって作成された消費者は、すべての製品更新を処理する必要はありません。これにより、ローカル テスト中の個人データの露出、トラフィック、偶発的な副作用が軽減されます。

raw ボディの Express エンドポイントを作成する

WooCommerce の署名は、送信される本文に基づいて計算されます。検証が完了するまで、これらのバイトを保存してください。署名ヘッダーには、16 進文字列ではなく、Base64 でエンコードされたバイナリ HMAC-SHA256 ダイジェストが含まれています。

import express from 'express';
import crypto from 'node:crypto';

const app = express();

function validWooSignature(rawBody, supplied, secret) {
  if (!supplied || !secret) return false;
  const expected = crypto
    .createHmac('sha256', secret)
    .update(rawBody)
    .digest('base64');
  const a = Buffer.from(supplied);
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

app.post(
  '/webhooks/woocommerce',
  express.raw({ type: 'application/json', limit: '2mb' }),
  async (req, res) => {
    const supplied = req.get('x-wc-webhook-signature');
    if (!validWooSignature(req.body, supplied, process.env.WC_WEBHOOK_SECRET)) {
      return res.sendStatus(401);
    }

    const payload = JSON.parse(req.body.toString('utf8'));
    await webhookInbox.insertOnce({
      deliveryId: req.get('x-wc-webhook-delivery-id'),
      topic: req.get('x-wc-webhook-topic'),
      payload,
    });
    return res.sendStatus(202);
  },
);

app.use(express.json());
app.listen(3000);

ルート固有の raw パーサーは、グローバル JSON パーサーの前に実行する必要があります。ミドルウェアが最初に本文を解析する場合、オブジェクトを再文字列化すると空白やエスケープが変更され、ダイジェストが無効になる可能性があります。これは、「」で説明されているのと同じ raw-body ルールです。 Webhook 署名ガイド、ただし、WooCommerce は特に Base64 出力を使用します。

HTTPSトンネルを開始する

  1. 受信機を起動し、受信していることを確認します http://localhost:3000
  2. 走る npx portpreview 3000 2番目のターミナルで。
  3. パブリック HTTPS URL をコピーして追加します /webhooks/woocommerce
  4. WordPress が最初の ping とトピック配信を送信している間、プロセスを実行し続けます。

wp-admin を開いたブラウザではなく、WordPress ホストがパブリック URL にアクセスできる必要があります。プライベートな開発プロセスに対してパブリックリクエストを行うトンネル橋。また、信頼された TLS も提供されるため、ルーター ポートを公開したり、独自のパブリック証明書をインストールしたりする必要はありません。

WooCommerce で Webhook を構成する

  1. 開ける WooCommerce → 設定 → 詳細 → Webhook
  2. 選択 Webhook を追加する そして、認識可能なローカル開発名を付けます。
  3. 選ぶ アクティブ ステータスと特定のトピック (注文の作成など)。
  4. 完全なトンネル配信 URL を貼り付けます。
  5. 長いランダムなシークレットを生成し、同じ値を WC_WEBHOOK_SECRET
  6. Webhook を保存し、テスト ストアでトピックをトリガーします。

アクティブな Webhook が初めて保存されるとき、WooCommerce は配信 URL に ping を送信します。 ping は接続を確認しますが、実際の注文ペイロードの代わりにはなりません。エンドポイントが最初のリクエストを許容できるようにしてから、選択したトピックを実行するためのテスト データを作成または更新します。

export WC_WEBHOOK_SECRET="$(openssl rand -base64 48)"

Base64 シークレットを環境ファイルに貼り付ける場合は、句読点が保持されるように引用符で囲みます。秘密は HMAC キーです。 WooCommerce REST API コンシューマ キーと WordPress パスワードは無関係の資格情報です。

ヘッダーを使用して配送のルーティングと追跡を行う

WooCommerce には便利なメタデータ ヘッダーが含まれています。バージョンと環境に応じて、これらにはトピック、リソース、イベント、ソース、Webhook ID、配信 ID が含まれます。 HTTP の要求に従って、名前の大文字と小文字を区別せずに扱います。ディスパッチにはトピックを使用し、トレーサビリティには配信 ID を使用しますが、必ず最初に本文を認証してください。

const handlers = {
  'order.created': handleOrderCreated,
  'order.updated': handleOrderUpdated,
  'product.updated': handleProductUpdated,
};

const handler = handlers[topic];
if (handler) await handler(payload);
else await recordUnsupportedTopic(topic);

JSON 形式のみからトピックを推測しないでください。作成された注文ペイロードと更新された注文ペイロードは似ていますが、正しい下流アクションは異なります。逆に、エンドポイントが受け入れるように構成されていないヘッダーとトピックの組み合わせを拒否します。

注文ペイロードを防御的に処理する

不変の識別子を使用する

注文番号の形式、顧客の電子メール、表示名ではなく、ストア ID と WooCommerce オブジェクト ID によってレコードを関連付けます。 2 つのストアは両方とも注文 ID 42 を持つことができるため、複数ストアの統合には複合キーが必要です。

拡張機能がフィールドを変更することを期待する

支払い、サブスクリプション、税金、チェックアウト、フルフィルメントの拡張機能では、メタデータと品目フィールドを追加できます。ビジネス ロジックに必要なフィールドを検証し、不明なフィールドを無視して、回帰テスト用にスキーマ バージョンまたは最小限の編集されたフィクスチャを保存します。

イベントの受信をフルフィルメントから分離する

注文が変更されたという Webhook は、永続キューまたは受信箱に入る必要があります。在庫の同期、配送ラベル、ERP コール、および顧客の電子メールは、確認後に実行する必要があります。これにより、遅い依存関係によって WooCommerce が成功した受信を配信の失敗として解釈することが防止されます。

状態遷移としてモデルを更新

注文は、保留中、処理中、保留中、完了、キャンセル、返金、または失敗の状態を経ることがあります。更新はすぐに行われる可能性があり、配信順序はタイムスタンプと現在のソース状態を比較するための安全な代替手段ではありません。繰り返されるトランジションを無害なものにします。

冪等性はコマース イベントには必須です

タイムアウトは、受信者がコミットした後、WooCommerce が応答を確認する前に発生する可能性があります。ハンドラーが冪等でない限り、再配信によって同じビジネス アクションが生成されます。配信 ID が存在する場合はそれを保存します。また、ストアごとに 1 つのフルフィルメント リクエストや注文の移行など、ドメイン レベルの一意性も強制します。

await db.transaction(async (tx) => {
  if (!(await tx.deliveries.claim(deliveryId))) return;
  await tx.orders.applyWooCommerceEvent(storeId, topic, payload);
  await tx.outbox.enqueueRequiredActions(storeId, topic, payload.id);
});

受信箱と送信箱のトランザクションにより、重複処理とフォローアップ作業の損失の両方を防ぎます。見る Webhook の再試行とべき等性 完全なパターンについては。

WooCommerce ログを使用して送信者側をデバッグする

WooCommerce は Webhook 配信を記録します。開ける WooCommerce → ステータス → ログ 公式ドキュメントに記載されている Webhook 配信ソースのフィルター。配信 URL、リクエスト時間、応答ステータス、および応答本文をローカル トンネル トレースと比較します。送信者のログには、WordPress がリクエストを試みたかどうかが記録されます。受信側のログは、アプリケーションが受信側で何を行ったかを示します。

編集されていない注文ペイロードを公開問題にコピーしないでください。これには、名前、請求先住所と配送先住所、電子メール、電話番号、製品の選択、支払いメタデータが含まれる場合があります。フィクスチャをバグの再現に必要なフィールドに減らします。

一般的な WooCommerce Webhook エラーのトラブルシューティング

Webhook が無効になります

WooCommerce は、5 回を超えて連続して配信が失敗すると、Webhook を自動的に無効にします。公式ガイドによれば、2xx、301、または 302 以外の応答は失敗としてカウントされます。エンドポイントを修正し、Webhook を再アクティブ化し、制御されたテストを送信します。とにかくリダイレ​​クトは避けてください。リダイレクトは署名のデバッグを複雑にし、署名された顧客データを意図しないホストに誤って送信する可能性があります。

署名は常に異なります

Webhook の設定されたシークレットを使用して正確な生の本文をハッシュし、バイナリ HMAC 出力を要求してから、それを Base64 エンコードします。ノードでは、つまり .digest('base64')。よくある間違いは、16 進数の使用、REST API シークレットの使用、最初に JSON を解析すること、または余分な改行バイトを含めることです。

最初の ping は機能しますが、注文イベントは機能しません

選択したトピックがトリガーしたアクションと一致することを確認します。オーダーの作成と既存のオーダーの変更は別のトピックです。ステータスがアクティブであることを確認し、WooCommerce ログをチェックして、プラグインまたはステージング キャッシュが基礎となるフックを妨げていないことを確認します。

ローカルリクエストは404を返します

フルパス、ルート方式、トンネルターゲットポートを確認してください。 WordPress は次の宛先に POST する必要があります /webhooks/woocommerce、単なるトンネルの起点ではありません。フレームワーク ミドルウェアは、Webhook をローカライズされたページまたは認証されたページにリダイレクトしないでください。

配信タイムアウト

認証されたイベントを永続化し、すぐに 200 または 202 を返します。リモート API 呼び出しと大量の変換をワーカーに移動します。ローカル ブレークポイントが、失敗として分類されるのに十分な時間リクエストを一時停止しているかどうかを確認します。

ペイロードを再生すると 401 が発生する

キャプチャされたリクエストは、正確な生のバイトと署名ヘッダーを保持する必要があります。 JSON を編集すると、元の署名が無効になります。ビジネス ロジック テストの場合は、検証境界の後にサニタイズされたフィクスチャを使用します。エンドツーエンド テストの場合は、専用のテスト シークレットを使用して新しい HMAC を生成します。フォローしてください 安全なリプレイワークフロー

ローカル ストア データのセキュリティ チェックリスト

  • 可能な限り、合成顧客と製品を使用してステージング ストアでテストします。
  • ローカル開発には固有の Webhook シークレットを使用し、公開後にローテーションします。
  • 本文を解析、ログ記録、またはキューに入れる前に、署名を検証してください。
  • 暗号検証後に、予想されるストア ソースとトピックをホワイトリストに登録します。
  • キャプチャからの住所、連絡先詳細、注文メモ、支払いメタデータを編集します。
  • TLS 検証を無効にしたり、wp-admin 資格情報を受信者に公開したりしないでください。

ローカル アーキテクチャは実稼働環境と一致する必要があります。HTTPS トランスポート、raw-body 認証、永続的な受け入れ、冪等処理、高速応答、監査可能なエラーなどです。異なる HMAC ヘッダーを持つ別のコマース プロバイダーについては、 Shopify ローカル Webhook ガイド

よくある質問

ローカルホストで WooCommerce Webhook をテストするにはどうすればよいですか?
HTTPS トンネルを使用してローカル POST ルートを公開し、WooCommerce Webhook 設定にそのパブリック URL を入力し、両側で同じシークレットを構成し、選択したトピックをトリガーします。
X-WC-Webhook-Signature を検証するにはどうすればよいですか?
構成された Webhook シークレットを使用して正確な生のリクエスト本文に対して HMAC-SHA256 を計算し、バイナリ ダイジェストを Base64 エンコードして、タイミングセーフにヘッダーと比較します。
WooCommerce が私の Webhook を無効にしたのはなぜですか?
WooCommerce は、5 回を超えて連続して配信が失敗すると Webhook を無効にします。接続、タイムアウト、または応答エラーを修正してから、再アクティブ化して再度テストします。
失敗した WooCommerce Webhook 配信はどこで確認できますか?
WooCommerce → ステータス → ログを開き、Webhook 配信ログをフィルターします。記録された応答をトンネルおよびローカル アプリケーション ログと比較します。