Category Archive お悩み・トラブル解決

Meta PixelとコンバージョンAPIの両方を設定する理由と手順

Meta PixelとコンバージョンAPIの両方を設定する理由と手順

WordPress で Facebook のコンバージョン API(CAPI)を使う場合、ブラウザ側の Meta Pixel とサーバー側の CAPI は両方とも設定するのが Meta 社の推奨する標準構成だ。Pixel ID は両方の設定に必要であり、CAPI だけを有効にして Pixel を無効にするのは推奨されない。

Meta Pixel とコンバージョン API はなぜ両方使うのか

Meta Pixel とコンバージョン API はなぜ両方使うのか

ブラウザ側の Meta Pixel は、サイト訪問者のブラウザ上で JavaScript が動作し、ページビューや購入完了といったイベントを直接 Facebook に送信する。仕組みがシンプルで設定も容易だが、広告ブロッカーやブラウザのプライバシー制限(ITP など)によってブロックされることがある。

一方、サーバー側のコンバージョン API(CAPI)は、WordPress サーバーから直接 Facebook のサーバーにイベントデータを送信する。ブラウザの制限を受けず、より確実にデータを届けられる。ただし CAPI 単体ではブラウザ上でのユーザー行動(スクロールやボタンクリックの細かなタイミングなど)を拾いにくい。

両方を併用することで、Pixel が拾ったイベントと CAPI が拾ったイベントを Facebook 側で重複排除( deduplication )し、欠損の少ない正確なデータが得られる。これが Meta 社の公式な推奨構成であり、Pixel Cat もこの併用を前提に設計されている。

Meta Pixel のみ
ブラウザの広告ブロッカーや ITP で10〜30% のイベントが欠損
CAPI のみ
ブラウザ側の細かな行動データが拾えず、オーディエンスの精度が低下
Pixel + CAPI 併用(推奨)
両方のデータを Facebook 側で重複排除し、最も正確なコンバージョン計測が可能
欠損あり  精度低下  推奨構成

各構成で得られるデータの質と欠損リスクの違いを表した概念図。併用時に Facebook 側で重複排除が働く。

Pixel Cat で推奨される設定手順

Pixel Cat で推奨される設定手順

Pixel Cat の管理画面では「Facebook Pixel」と「Conversions API」の両方にチェックを入れて有効化する。Pixel ID は両方のセクションに同じ ID を入力する必要がある。これは CAPI がどの Pixel アカウントに紐づくイベントかを識別するために使われるもので、Pixel 側と CAPI 側がそれぞれ独立して動作しながら同じアカウントにデータを送る仕組みだ。

STEP 1 Pixel Cat 設定画面で「Facebook Pixel」を有効化し Pixel ID を入力
STEP 2 同じ画面で「Conversions API」を有効化し、同じ Pixel ID を入力
STEP 3 CAPI 用のアクセストークンを Facebook イベントマネージャから生成して入力
STEP 4 Facebook イベントマネージャの「テストイベント」タブで両方のデータ受信を確認

Pixel Cat で両方を有効化する際の設定フロー。Pixel ID は両方に同じものを入力する。

Facebook Pixel セクションの設定

Pixel Cat の「Facebook Pixel」タブを開き、「Enable Facebook Pixel」をオンにする。表示されたフィールドに Facebook イベントマネージャで確認できる Pixel ID(15桁の数字)を入力する。標準イベント(PageView や Purchase など)はデフォルトでトラッキング対象になるが、必要に応じてカスタムイベントを追加できる。

Conversions API セクションの設定

Pixel Cat の「Conversions API」タブに移動し、「Enable Conversions API」をオンにする。ここでも同じ Pixel ID を入力する。Pixel ID の入力が必須なのは、CAPI がサーバーからイベントを送信する際に「どの Pixel アカウント宛か」を特定する必要があるためだ。ブラウザ Pixel とは通信経路が異なるだけで、最終的なデータの宛先は同じアカウントになる。

次に Facebook イベントマネージャでアクセストークンを生成する。イベントマネージャの「設定」タブから「アクセストークンを生成」を選び、Pixel Cat の該当フィールドに貼り付ける。トークンは CAPI が Facebook のサーバーと認証するための鍵であり、これがないとイベントを送信できない。

重複排除の仕組みを確認する

Pixel と CAPI を両方有効にすると、同じイベント(例: 購入完了)がブラウザ経由とサーバー経由の2回 Facebook に届く可能性がある。これを防ぐために、Pixel Cat は各イベントに一意のイベント ID を付与し、両方の経路で同じ ID を送る。Facebook 側は同一 ID のイベントを重複と判断して1件として計上する。この仕組みにより、データの欠損を減らしつつ二重計上を防ぐことができる。

Pixel を無効にして CAPI だけにするとどうなるか

Pixel を無効にして CAPI だけにするとどうなるか

Pixel Cat で Facebook Pixel を無効にし CAPI のみを有効にすることは技術的には可能だ。しかしこの設定では、ブラウザ上で動作する Pixel が提供するオーディエンスデータ(サイト滞在時間やスクロール深度など)が一切取得できなくなる。これにより Facebook 広告のオーディエンス構築やリターゲティングの精度が大幅に落ちる。

また CAPI 単体では、ブラウザの Cookie に依存しない代わりに、ユーザーのブラウザ情報(ユーザーエージェントや IP アドレス)をサーバー側から送る必要がある。これを適切に処理しないと Facebook 側でイベントのマッチング率が下がり、期待したほど正確なデータが得られない場合もある。特別な理由がない限り、Pixel と CAPI の併用が基本構成だ。

設定後の動作確認とテスト方法

設定後の動作確認とテスト方法

設定が完了したら、Facebook イベントマネージャの「テストイベント」タブを開く。サイト上で実際にページを閲覧したり、テスト購入を行ったりすると、ブラウザ Pixel からのイベントとサーバー CAPI からのイベントがそれぞれ表示される。両方の経路でイベントが届いていれば正常だ。

ブラウザの開発者ツール(F12)で Network タブを確認し、Facebook のドメインに向けたリクエストが発生していることも確認できる。CAPI はサーバー間通信のためブラウザの Network タブには表示されないが、イベントマネージャ上で「サーバー」と表示されるイベントがあれば問題なく動作している。

よくある質問

Pixel ID は Pixel と CAPI で別々に取得する必要があるか

同じ Pixel ID を使う。Pixel ID は Facebook 広告アカウントに紐づく一意の識別子で、ブラウザ Pixel も CAPI もこの ID 宛にデータを送信する。別々に取得する必要はなく、イベントマネージャで確認できる1つの ID を両方に入力すればよい。

CAPI のアクセストークンはどこで取得するのか

Facebook イベントマネージャの「設定」タブ内にある「アクセストークンを生成」ボタンから作成する。トークンは一度生成すると再表示できないため、コピーして安全な場所に保管する。漏洩すると第三者にイベント送信に利用されるリスクがある。

無料の Pixel Cat プラグインで CAPI は使えるか

Pixel Cat の無料版でも CAPI の基本機能は利用できる。ただし一部の高度なイベント(カスタムイベントの詳細設定や高度なマッチング機能)は有料版限定の場合がある。まずは無料版で Pixel と CAPI の両方を有効にし、イベントマネージャでデータが届くことを確認するのがよい。

CAPI 導入後、Facebook 広告の計測はすぐに改善するか

設定後すぐにイベントの受信は始まるが、Facebook 側のデータ処理や学習には数日かかることがある。広告パフォーマンスの変化を評価する際は、少なくとも1〜2週間のデータで判断する。また広告セットのコンバージョンウィンドウ設定も併用構成に合わせて見直すと効果が出やすい。

この記事のポイント

  • Meta 社の推奨はブラウザ Pixel とサーバー CAPI の併用である
  • Pixel ID は両方の設定に同じものを使用する
  • CAPI だけの運用はオーディエンスデータの欠損で広告精度が下がる
  • 設定後はイベントマネージャのテストタブで両経路の受信を確認する
  • 重複排除はイベント ID によって自動的に行われる
URLに特定の単語を含むリンクを一括でホームページに置換する方法

URLに特定の単語を含むリンクを一括でホームページに置換する方法

URL に特定の単語(例 sandwich)を含む全リンクを一括でホームページに置換するには、Search Regex プラグインか phpMyAdmin の正規表現置換を使う。単純な完全一致検索しかできないツールでは対処できないため、部分一致の条件を指定できる方法が必須になる。

なぜ通常の「Better Search Replace」では置換できないのか

なぜ通常の「Better Search Replace」では置換できないのか

「Better Search Replace」のような一般的なプラグインは、検索文字列とまったく同じ URL しか見つけられない。旧サイトから移管した際に「sandwich-f07abf」や「sandwich/xyz」のように末尾にランダムな文字列が付与されたリンクが数百件ある場合、完全一致で一つひとつ指定するのは現実的ではない。今回のように「URL の一部が特定のキーワードで、あとは異なる」パターンには、正規表現によるパターンマッチが必要になる。

Search Regex プラグインで部分一致 URL を一括置換する

Search Regex プラグインで部分一致 URL を一括置換する

Search Regex は、正規表現を使ってデータベース内の投稿やカスタムフィールド、オプションなどを検索・置換できるプラグインだ。ドライラン(事前確認)機能がなく直接置換が走るため、必ず事前にデータベース全体のバックアップを取る必要がある。

設定手順

STEP 1 Search Regex をインストールして有効化する
STEP 2 検索パターンに http[^\s]*sandwich[^\s]* を入力
STEP 3 置換後文字列に / を入力
STEP 4 「Replace」を実行(事前に必ずバックアップを取る)

Search Regex では、検索対象のカラム(post_content、post_excerpt、guid など)やテーブルを選択できる。すべてにチェックを入れると想定外のレコードまで置換されることがあるため、最初は post_content だけに絞って実行し、結果を確認するのが安全だ。置換に成功した場合、変更の取り消しは手動で行う必要がある点を覚えておく。

検索パターンの正規表現解説

http[^\s]*sandwich[^\s]* は「http で始まり sandwich を含み空白文字が出るまでの連続した URL」を意味する。[^\s]* の部分で、sandwich の前後にどんな文字が並んでいても対象に含めることができる。これにより sandwich-f07abf も sandwich/xyz もすべて拾える。もしホームページではなく完全に削除したい場合は、置換後文字列を空欄にすればよいが、リンク切れを起こすよりもホームページへ誘導するほうが SEO 上も望ましい。

Before(エラー状態)
https://example.com/sandwich/xyz → 404
https://example.com/sandwich-f07abf → 404
After(修正後)
https://example.com/ → ホームページ
https://example.com/ → ホームページ
エラー状態  修正後

phpMyAdmin でデータベースから直接置換する方法

phpMyAdmin でデータベースから直接置換する方法

より高度な操作として、phpMyAdmin を使う方法もある。phpMyAdmin はレンタルサーバーの管理画面からアクセスできる MySQL データベース操作ツールだ。検索機能で該当するレコードを洗い出したあと、SQL の UPDATE 文で一括置換する。

特定のキーワードを含むレコードを検索する

phpMyAdmin にログインし、WordPress のデータベースを選択する。「検索」タブでキーワード「sandwich」を入力し、全テーブルを対象に検索をかける。該当行が表示されるので、どのテーブルのどのカラムに URL が含まれているかを特定できる。

SQL で一括置換をかける

影響範囲を特定したら、次のような UPDATE 文を実行する。ここでも誤操作を防ぐため、必ず事前にバックアップを取る。

UPDATE wp_posts SET post_content = 
REPLACE(post_content, 
'https://example.com/sandwich-f07abf', 
'/')
WHERE post_content LIKE '%sandwich%';

ただし、この方法は完全一致の REPLACE 関数を使うため、ランダム文字列が多様な場合は検索文字列を動的に扱えない。代わりに REGEXP_REPLACE が使える MySQL 8.0 以降の環境、または MariaDB 10.0.5 以降なら、正規表現による置換が行える。

UPDATE wp_posts SET post_content = 
REGEXP_REPLACE(post_content, 
'https?://[^\s]*sandwich[^\s]*', 
'/')
WHERE post_content REGEXP 'https?://[^\s]*sandwich[^\s]*';

この SQL は、http または https で始まり sandwich を含み空白が出るまでの URL をすべて抜き出し、ホームページ(/)に置換する。データベース全体にわたって同様の処理が必要なら、postmeta や options テーブルなどにも同じ UPDATE 文を適用する。

置換前に必ず取るべき安全策

置換前に必ず取るべき安全策

Search Regex も phpMyAdmin も、一度実行すると元に戻せない操作になる。必ず次の 3 つを行う。

  • データベース全体のエクスポート(バックアップ)を取る
  • 可能ならステージング環境で先にテストする
  • 置換後はサイト全体を巡回し、表示崩れやリンク切れがないか確認する

ステージング環境が用意できない場合は、本番で実行する前に影響範囲を最小に絞る。Search Regex であれば、最初は post_content だけを対象にし、問題なければ他のカラムを追加していくと安全だ。

よくある質問

Search Regex と「Better Search Replace」はどう使い分ける?

完全に同じ文字列しか置換できないのが Better Search Replace で、部分一致や正規表現を使いたい場合は Search Regex になる。ただし Search Regex はドライランができないので、安全を重視するなら、まず Better Search Replace で置換できる部分を先に処理し、残った複雑なパターンだけを Search Regex で片付ける手順が堅実だ。

phpMyAdmin で誤って必要なデータまで置換してしまったら?

バックアップファイルをインポートして復元する。phpMyAdmin の「インポート」タブからエクスポートしておいた SQL ファイルを選択し実行すれば、置換前の状態に戻せる。バックアップを取らずに操作してしまった場合は、復元は極めて困難になるため、作業前のバックアップは必須だ。

置換後に画像や内部リンクが壊れていないか心配だ

リンクチェッカー系のプラグイン(Broken Link Checker など)を一時的に導入し、サイト全体のリンク切れをスキャンするとよい。置換してから数時間後に確認すれば、見落としがあっても早期に気づける。スキャン後は負荷を避けるため、プラグインを無効化しておく。

URL の一部に「sandwich」を含むが、それ以外の部分は維持したい場合は?

キャプチャグループ(丸括弧)を使う。たとえば sandwich より前のパスだけを残したいなら (https?://[^\s]*)sandwich[^\s]* とし、置換後文字列に $1 を指定する。置換の条件は柔軟に調整できるため、削除する範囲や残す範囲を細かく制御できる。

Search Regex の代わりに WP-CLI で置換できる?

WP-CLI が使える環境なら wp search-replace コマンドで正規表現を扱える。ただし部分一致のためには --regex オプションを使う必要があり、さらに複雑なパターンになる。コマンドラインに慣れている開発者向けの手段といえる。

この記事のポイント

  • URL に特定の単語を含むリンクを一括置換するには正規表現が必須
  • Search Regex プラグインで部分一致をパターン指定して置換できる
  • phpMyAdmin の REGEXP_REPLACE でも同様の処理が可能
  • いずれの方法でも事前のデータベースバックアップが最優先
  • 置換後はリンク切れチェックでサイトの健全性を確認する
WooCommerce Mollie決済プラグイン更新後の致命的エラー対処法

WooCommerce Mollie決済プラグイン更新後の致命的エラー対処法

WooCommerce の Mollie 決済プラグイン(Mollie Payments for WooCommerce)をバージョン 8.1.8 から 8.1.9 に更新した直後、サイトに「このサイトで重大なエラーが発生しました」と表示されたり、WordPress から致命的エラーの通知メールが届いたりする場合は、プラグイン内部のコンストラクタが想定する引数の数と実際に渡される引数の数が一致しないことが直接の原因だ。バージョン 8.1.8 へのロールバックで即座に復旧できる。

Mollie プラグイン更新後に起きる致命的エラーの正体とは

Mollie プラグイン更新後に起きる致命的エラーの正体とは

今回のエラーは「ArgumentCountError(引数の数が一致しない)」に分類される。具体的には、プラグイン内部の RestApi.php というファイルの 26 行目に定義された __construct() メソッド(クラスの初期化時に呼び出される特別な関数)が 4 つの引数を必要としているにもかかわらず、呼び出し元の services.php 127 行目から 3 つしか渡されていない。

この種の不具合は、プラグインの開発過程でメソッドのシグネチャ(引数の数や型の定義)が変更されたにもかかわらず、すべての呼び出し箇所が追従しなかった場合に発生する。今回のケースでは 8.1.8 から 8.1.9 へのアップデートで RestApi クラスのコンストラクタに新しい依存オブジェクトが 1 つ追加されたが、サービスコンテナ側の定義が更新に追いつかず、3 つのまま残ってしまった可能性が高い。

このエラーは Mollie プラグインの開発元も再現できておらず、特定の環境(PHP バージョンや他のプラグインとの組み合わせ)でのみ発生する。そのため、原因の完全な特定と恒久的な修正には開発元の調査を待つ必要がある。

Before(エラー状態)
プラグイン更新後、管理画面とサイトに「このサイトで重大なエラーが発生しました」と表示される
エラーログに「Too few arguments to function」のメッセージ
チェックアウトページが動作しない、または管理画面の一部が読み込めない
After(ロールバック後)
サイトと管理画面が正常に表示される
Mollie 決済機能が通常通り動作する
致命的エラーの通知メールが停止する
エラー状態  回復後

上図のとおり、ロールバックによってサイトの全機能が即座に回復する。このエラーは PHP の実行を完全に停止させる E_ERROR レベルのため、チェックアウトページを含むサイト全体に影響が及ぶ点が深刻だ。

バージョン 8.1.8 へロールバックして即時復旧する手順

バージョン 8.1.8 へロールバックして即時復旧する手順

最も確実で安全な対処法は、プラグインを直前の安定バージョンである 8.1.8 に戻すことだ。管理画面にアクセスできる場合とできない場合で手順が異なる。

管理画面にアクセスできる場合のロールバック

管理画面にログインできる状態であれば、WP Rollback プラグインを使うのが最も簡単だ。このプラグインは、WordPress.org の公式プラグインディレクトリに登録された任意のプラグインを、過去の特定バージョンにワンクリックで戻せる。

STEP 1 「プラグイン」→「新規追加」から WP Rollback をインストールして有効化する
STEP 2 「プラグイン」→「インストール済みプラグイン」で Mollie Payments for WooCommerce を探す
STEP 3 プラグイン名の下に表示される「ロールバック」リンクをクリックする
STEP 4 バージョン一覧から「8.1.8」を選択してロールバックを実行する

WP Rollback を使わない場合は、プラグインを一度削除してから旧バージョンを手動でインストールする。削除しても Mollie の API キーや決済設定はデータベースに残るため再設定は不要だが、念のため作業前に WooCommerce のシステムレポートを控えておくと安心だ。

管理画面にもアクセスできない場合の復旧

エラーによって管理画面にも入れなくなっている場合は、FTP クライアントまたはレンタルサーバーのファイルマネージャーを使って対処する。手順は以下のとおりだ。

  1. FTP でサーバーに接続し、/wp-content/plugins/ ディレクトリに移動する
  2. mollie-payments-for-woocommerce フォルダの名前を「mollie-payments-for-woocommerce-broken」などに変更する(これでプラグインが無効化され、管理画面に入れるようになる)
  3. 管理画面にログインしたら、WP Rollback をインストールする
  4. フォルダ名を元に戻してから、STEP 1〜4 を実行して 8.1.8 にロールバックする

フォルダ名の変更でプラグインを無効化するとサイトのフロントエンドも正常に表示されるようになるが、その間 Mollie 決済は利用できない点に注意する。

手動 ZIP アップロードで 8.1.9 を試す場合の注意点

手動 ZIP アップロードで 8.1.9 を試す場合の注意点

フォーラムの一部ユーザーは、WordPress 管理画面の自動更新ではなく GitHub からダウンロードした ZIP ファイルを手動アップロードすることでエラーを回避できたと報告している。しかし別のユーザーは同じ手順でもエラーが再発しており、確実な回避策ではない。

手動 ZIP アップロードを試す場合は、以下の点に注意する必要がある。まず、GitHub のリリースページ(Mollie の公式 WooCommerce リポジトリ)から 8.1.9 の ZIP を入手する。プラグイン画面の「新規追加」→「プラグインのアップロード」から ZIP を選択し、「既存のプラグインと置き換える」を確認してアップロードする。

手動アップロード後はサイト全体をくまなく確認し、特に実際のテスト購入でチェックアウトフローが最後まで動作することを確かめる。エラーが再発した場合は速やかに 8.1.8 に戻す。

調査中の自動更新を止めて再発を防ぐ

調査中の自動更新を止めて再発を防ぐ

開発元が修正版をリリースするまでの間、Mollie プラグインが勝手に 8.1.9 に再更新されるのを防ぐ必要がある。WordPress の自動更新設定ではプラグイン単位で自動更新のオンオフを切り替えられる。

「プラグイン」→「インストール済みプラグイン」で Mollie Payments for WooCommerce の行を見ると「自動更新を有効化」または「自動更新を無効化」のリンクがある。これをクリックして自動更新を無効にしておけば、8.1.8 のまま安全に運用を継続できる。修正版がリリースされたら、自動更新を再度有効にしてから手動で更新を実行する。

よくある質問

8.1.8 を使い続けてもセキュリティ上の問題はないか

8.1.8 と 8.1.9 の差分は軽微な機能追加やバグ修正が中心であり、8.1.8 に既知の重大な脆弱性は報告されていない。数週間程度の運用であれば実務上のリスクは低い。とはいえ、決済プラグインに限らず常に最新バージョンを使うのが基本のため、修正版がリリースされたら速やかに更新する。

手動 ZIP アップロードと管理画面からの自動更新で何が違うのか

一般的には同じ ZIP ファイルを使うため内容に差はないが、自動更新時には WordPress のアップデーターがファイルの置き換えを段階的に行うのに対し、手動アップロードでは一度に全ファイルが上書きされる。キャッシュやオートローダーの生成タイミングの違いが結果に影響している可能性がある。ただし本件では原因が完全に特定されていないため、効果には個体差がある。

PHP バージョンはエラーに関係するか

関係する可能性は高い。PHP 8.0 以降は引数の数の不一致に対して E_ERROR レベルの厳格なエラーを出すが、PHP 7.x では E_WARNING で済んでいたケースもある。Mollie プラグインのシステム要件を確認し、推奨される PHP バージョン(通常 7.4 以上)を使っているかどうかを WooCommerce のステータス画面で確認する。

エラーメールが大量に届いて困っている。どう止めればよいか

WordPress の致命的エラー通知はサイトにアクセスがあるたびに発生するため、更新直後は短時間で大量のメールが届くことがある。最も早い対処は前述のとおり FTP でプラグインフォルダの名前を変更して無効化することだ。メールが止まったら、すぐに 8.1.8 へのロールバックに取りかかる。

他の決済プラグインに切り替えるべきか

このエラーはバージョン 8.1.9 固有の一時的な不具合であり、Mollie プラグイン全体の品質に問題があるわけではない。8.1.8 で問題なく運用できていたのであれば、慌てて乗り換える必要はない。オランダ発の Mollie は欧州で高いシェアを持つ決済プロバイダーであり、プラグインも活発にメンテナンスされている。

この記事のポイント

  • Mollie 8.1.9 の致命的エラーはコンストラクタ引数の数が一致しないことが原因
  • 最も確実な対処は WP Rollback で 8.1.8 に戻すこと
  • 管理画面に入れない場合は FTP でプラグインフォルダをリネームして無効化する
  • 手動 ZIP アップロードは回避できる場合とできない場合があり確実性に欠ける
  • 修正版が出るまで自動更新を無効にして 8.1.8 のまま運用する
Events ManagerでGutenbergのイベントが公開できない時の直し方

Events ManagerでGutenbergのイベントが公開できない時の直し方

Events ManagerをGutenberg編集モードで使っているときに新規イベントが公開できず、クラシックエディタでは問題なく動作する場合、プラグインのバージョンが7.3.1〜7.3.4のいずれかであることが主な原因だ。7.3.5以降へアップデートすると修正される。

どんな操作をしたときに発生するのか

どんな操作をしたときに発生するのか

Gutenbergモードを有効にしたEvents Managerで新規イベントを作成する。すべての項目を入力して「公開」ボタンを押しても、画面が再読み込みされステータスが「下書き」のままになり、公開状態に切り替わらない。一方でクラシックエディタに切り替えると、同じ内容でも問題なく公開できるという状況だ。

この現象は、WP標準テーマ(Twenty Twenty-FourやTwenty Twenty-Five)に切り替えても、他のプラグインをすべて無効化しても変わらない。Events Manager側のGutenberg統合部分にバージョン固有の不具合が存在しているために起きる。

公開ボタンが反応しない直接の原因は何か

公開ボタンが反応しない直接の原因は何か

Events Managerのバージョン7.3.1から7.3.4には、Gutenbergエディタ上でイベントを保存する際に走るバリデーション(検証)処理に問題がある。具体的には、イベントの必須項目が正しく入力されていても内部的な検証に失敗し、「公開」操作が受理されない状態になる。

とくに繰り返しイベント(定期的な開催設定)を扱う場合、「Main recurrence set times are required(メインの繰り返し時刻設定が必要です)」という趣旨の検証エラーが返され、公開をブロックされるケースが報告されている。このバリデーションエラーは管理画面の見た目には表示されず、ブラウザの開発者ツール上で確認できる。

エラー状態 Gutenbergでイベントを保存しようとする
内部処理 EMのバリデーションAPIが検証失敗を返す(7.3.1〜7.3.4の不具合)
結果 ステータスが「下書き」のまま公開されない
公開に失敗する流れ(Events Manager 7.3.1〜7.3.4)

このデモが示すように、エディタの見た目上は正常に操作しているのに、プラグイン内部のAPI応答が原因で公開処理が止まる。Events Manager 7.3.5でこのバリデーション不具合が修正されている。

Events Managerを最新版にアップデートして修正する

Events Managerを最新版にアップデートして修正する

最も確実な解決策は、Events Managerをバージョン7.3.5以降にアップデートすることだ。管理画面から数ステップで完了する。

STEP 1 WordPress管理画面で「ダッシュボード」→「更新」を開く
STEP 2 Events Managerに更新がある場合「プラグイン」一覧から更新する
STEP 3 更新後、Gutenbergで新規イベントを作成し公開できるか確認する

サイトの運用途中でアップデートをためらう場合は、まずステージング環境(テスト用の複製サイト)でアップデート後の動作を確認すると安全だ。近年の国内レンタルサーバーでは、管理パネルからワンクリックでステージング環境を作成できるものも多い。

すぐに公開したい場合の一時的な回避策

すぐに公開したい場合の一時的な回避策

プラグインのアップデートが何らかの理由ですぐにできない場合、以下の回避策で公開できることがある。

  • 公開ボタンを2回以上連続でクリックする。1回目でいったん下書きとして保存され、2回目以降のクリックで公開状態に切り替わるケースが報告されている。
  • イベント編集画面の「Events Manager」設定パネルで、Gutenbergモードを無効にしてクラシックエディタを使う。クラシックエディタでは問題なく公開できる。

これらの回避策は、あくまでアップデート前の応急処置として使う。根本的には7.3.5以降へのアップデートが必要だ。

アップデート後も繰り返しイベントでエラーが出る場合の対処

アップデート後も繰り返しイベントでエラーが出る場合の対処

7.3.5以降でも、繰り返しイベントの設定時にまれに「Main recurrence set times are required(メインの繰り返し時刻設定が必要です)」という趣旨のバリデーションエラーが表示されることがある。このエラーは、繰り返し設定の中核となる日時情報がバリデーションAPIに正しく渡っていない場合に発生する。

まず試すべきは、繰り返し設定を一度クリアして再入力することだ。とくに開始日時と終了日時、および繰り返しパターンの「初回の日時」が空欄になっていないか確認する。カスタムコードでGutenberg有効化を制御していた場合は、そのコードが完全に削除されているかも確認する。残留したコードがAPI通信に干渉している可能性がある。

よくある質問

Events ManagerのGutenbergモードはどこで切り替えられるか

管理画面の「Events」→「設定」→「管理画面」タブにある「イベントエディタの種類」で切り替えられる。ここで「Gutenberg」を選択するとブロックエディタが有効になり、「クラシックエディタ」を選ぶと従来の編集画面に戻る。

Gutenberg有効化のカスタムコードが原因になることはあるか

過去にfunctions.phpなどへ追加したGutenberg有効化コードが削除されずに残っていると、プラグインの設定と競合して予期しない動作を起こす可能性がある。コードが完全に削除されているか、もしくはコメントアウトされているか確認する。

公開ボタンを押しても何も反応しない場合はどうすればよいか

ブラウザの開発者ツール(F12キー)の「コンソール」タブにJavaScriptエラーが表示されていないか確認する。別のプラグインがGutenbergと競合してJavaScriptエラーを起こしている場合、それが原因で公開処理が止まることがある。

クラシックエディタでは問題ないのにGutenbergだけ不具合が出る理由は何か

GutenbergはREST APIを介してデータを保存する仕組みをとっている。Events Managerのバリデーション処理も、GutenbergモードではAPI経由で実行される。クラシックエディタの場合は異なる保存経路を使うため、API側の不具合の影響を受けずに公開できる。

7.3.5はいつリリースされたのか

Events Manager 7.3.5は2026年7月下旬にリリースされ、本件のGutenberg公開不具合が修正されている。管理画面の更新通知から適用できる。

この記事のポイント

  • Events Manager 7.3.1〜7.3.4のGutenbergモードには公開できない不具合がある
  • 7.3.5以降へアップデートすると修正される
  • アップデートできない場合は公開ボタンの複数回クリックやクラシックエディタで一時回避できる
  • 繰り返しイベントでの検証エラーは設定の再入力で直ることが多い
  • 過去のカスタムコードが競合していないか確認することも大切だ
LiteSpeed Cacheでパージ成功してもキャッシュが残る原因と直し方

LiteSpeed Cacheでパージ成功してもキャッシュが残る原因と直し方

LiteSpeed Cacheで管理画面やWP-CLIから「Purge All(全キャッシュ削除)」を実行し成功メッセージが出ているにもかかわらず、公開ページがいつまでも古い内容のまま更新されない場合、プラグインのキャッシュ制御と実際に動作しているサーバーレベルのキャッシュ層との間に不整合が起きている可能性が高い。根本的には、LSCacheプラグインの設定最適化と、場合によってはプラグインを一時的に無効化しての強制リフレッシュが有効な解決策になる。

なぜ「全削除」に成功してもキャッシュが残り続けるのか

なぜ「全削除」に成功してもキャッシュが残り続けるのか

LiteSpeed Cacheのキャッシュ構造は多層的で、プラグインの管理画面と実際のキャッシュストレージが常に一対一で対応しているとは限らない。管理画面で「Purge All」を実行すると、プラグインは内部的にパージタグを生成し、LSWS(LiteSpeed Web Server)に対してキャッシュ削除の指示を出す。ここで成功メッセージが返ってくるのは、あくまで「指示が出せた」という意味であり、ディスクやメモリ上の実ファイルが完全に消えたことの保証にはならない。

まず試すべきプラグイン側の設定見直し

まず試すべきプラグイン側の設定見直し
修正前の状態
パージを実行しても、レスポンスヘッダーに x-litespeed-cache:hit が返ってくる。
x-litespeed-cache: hit
x-litespeed-cache-control: no-cache
修正後の状態
キャッシュヘッダーが miss になり、サーバーが動的生成に切り替わった。
x-litespeed-cache: miss
キャッシュヒットして古い内容が表示される  キャッシュミスで最新の内容が表示される

キャッシュ有効期限とブラウザキャッシュ設定の確認

まず、LSCacheプラグインの「キャッシュ」タブでTTL(Time To Live、キャッシュの有効期限)が極端に長く設定されていないか確認する。デフォルトは604800秒(1週間)だが、公開ページの更新頻度が高いサイトでは3600秒(1時間)程度に短くすることで、パージ操作の効果が出やすくなる。また「ブラウザキャッシュ」タブで、ブラウザ側のキャッシュ保持期間が長すぎると、サーバーのパージ後もユーザーのローカルキャッシュが優先されて古い表示になる。短期間に設定するか、問題切分け中は一時的に無効化(オフ)にする。

オブジェクトキャッシュとRedisの影響を見極める

RedisやMemcachedといった外部オブジェクトキャッシュを使っている環境では、LSCacheがページキャッシュを削除しても、データベースクエリの結果がオブジェクトキャッシュに残り、結果として同じ古い情報でページが再生成される。Redisを使っているなら、管理画面の「LiteSpeed Cache」→「オブジェクトキャッシュ」でステータスを確認し、「Purge Object Cache」を手動で実行する。それでも直らない場合は、問題の切分けとしてredis-cacheやRedis Object Cacheプラグイン自体を一度無効化し、LSCacheだけの状態でパージを試す。

サーバーレベルで強制的にキャッシュを削除する手順

プラグインの操作で改善しない場合、LiteSpeed Web Serverが保持しているキャッシュをOSレベルで手動削除する。特に、LSCacheプラグインが生成したキャッシュ情報と、LSWSの内部キャッシュマップがずれてしまった場合に有効だ。

サーバーレベルの強制キャッシュクリア手順
STEP 1 SSHでサーバーにログインし、LSWSのキャッシュディレクトリを特定する
STEP 2 LSWSを完全停止し、スワップファイルとキャッシュファイルをすべて削除する
STEP 3 LSWSを起動し、LSCacheプラグインの「Purge All」を再度実行する
STEP 4 ブラウザのシークレットモードで動作を確認する

ディスクキャッシュの格納場所と削除コマンド

SSHでサーバーに接続し、まずLSWSのキャッシュパスを特定する。デフォルトでは /tmp/lshttpd/ または /usr/local/lsws/cachedata/ 以下にキャッシュが格納されている。LSCacheプラグインの「CDN/キャッシュ設定」にある「キャッシュルートパス」を確認すると確実だ。

次に、LSWSを完全に停止する。systemctl restart lsws や管理画面からのグレースフルリスタートではプロセスがクリアされず、内部のキャッシュマップが生き残る。以下の手順で、キャッシュディレクトリを物理的に空にしてから再起動する。

# LSWSを完全停止
/usr/local/lsws/bin/lswsctrl stop

# キャッシュディレクトリとスワップを完全に削除
rm -rf /tmp/lshttpd/swap/*
rm -rf /tmp/lshttpd/cache/*

# LSWSを起動
/usr/local/lsws/bin/lswsctrl start

起動後、WordPress管理画面からLSCacheの「Purge All」を実行し、ブラウザのシークレットウィンドウ(または開発者ツールでキャッシュを無効化した状態)で動作を確認する。x-litespeed-cache ヘッダーが miss になっていれば成功だ。

どうしても治らない場合の一時的切り分け

上記の手順を実行しても、ベアURL(パラメータなしの通常アクセス)だけが古いキャッシュを返し続ける場合、LSCacheプラグイン自体がリクエスト段階でキャッシュの再取得を意図せず阻害している可能性が高い。この状況は、特定の条件下でLSCacheプラグインがブラウザやリバースプロキシに強力なCache-Controlヘッダーを設定し、サーバー側でミスになってもCDNやブラウザが古いデータを返し続けるケースだ。

最終的な切分けとして、LSCacheプラグインを5分〜10分間だけ完全に無効化する。無効化後に即座にキャッシュが更新されるなら、LSCacheプラグインの内部ロジックまたは設定が主因であると特定できる。プラグインを再有効化した後、デフォルト設定へのリセットや、問題を再現させた設定項目を一つずつ絞り込む。

よくある質問

クエリ文字列を付けるとキャッシュがバイパスされる理由は?

LiteSpeed Cacheは、URLにパラメータ(?=xxx)が付与されたリクエストを、デフォルトでキャッシュ対象外とみなす。そのためベアURLでは x-litespeed-cache:hit で古いキャッシュが返っているのに、/?v=2 のような文字列を付けると miss となり、動的に生成された最新ページが表示される。

サーバーを再起動できない共有サーバーではどう対処すればよいか

多くの共用サーバーではSSHやLSWSの制御権限が制限されている。この場合、LSCacheプラグインの「ツールボックス」→「Purge All」を実行し、即座にプラグインを無効化する。その後「LiteSpeed Cache」を再有効化し、デフォルト設定へのリセットを試す。サーバー側のキャッシュディレクトリに触れない環境では、この手順が最も確実な強制リセットになる。

パージ後のキャッシュ再生成を防ぎたい場合の設定は?

公開前のプレビューや検証でキャッシュを完全に止めたい場合、LSCacheプラグインの「キャッシュ」→「キャッシュを有効化」のトグルを一時的にオフにする方法が最も確実だ。ただしこの設定はサイト全体のパフォーマンスに影響するため、検証後は必ずオンに戻し、特定のページだけ除外したい場合は「URI 除外」機能を使う。

この記事のポイント

  • LSCacheのパージ成功表示が実キャッシュ削除の保証にはならない
  • サーバーレベルでディスクキャッシュを直接削除すると治るケースが多い
  • Redisなどの外部オブジェクトキャッシュも同時に削除する必要がある
  • クエリ文字列でバイパスされる現象はLSCacheの正常動作だが、ベアURLが古いのは異常
  • どうしても治らなければ、プラグインの一時無効化で原因をLSCacheに特定できる
WordPress wp2shell攻撃後の完全クリーンアップと再発防止手順

WordPress wp2shell攻撃後の完全クリーンアップと再発防止手順

WordPress が REST Batch API を悪用した wp2shell 攻撃を受け、Web シェルを仕込まれたり偽の管理者を作られたりした場合は、WordPress 本体の更新だけでなくファイルとデータベースの完全な掃除が必要になる。攻撃者は認証なしでコードを実行できるため、必ず FTP/SSH と SQL の両面から対処する。

この攻撃は SQL インジェクションで PHP ファイルをサーバーに直接書き込み、データベース内にも偽のメニュー項目や changeset を残す。パッチを当てただけではバックドアが生き残り、再侵入される危険がある。

Before 攻撃直後、WordPress だけ更新した状態
✗ /wp-content/cache/ に不明な PHP ファイルが残る ✗ データベースに偽の customize_changeset が残る ✗ 攻撃者の管理者アカウントが有効なまま ✗ 全員のセッションが生きている
After 完全クリーンアップ後の状態
✓ キャッシュ内の Web シェルを全削除 ✓ DB から偽データを削除し FILE 権限を剥奪 ✓ 全員のパスワード変更とセッション強制切断 ✓ DISALLOW_FILE_MODS でファイル改変を遮断

上図は攻撃直後と完全クリーンアップ後の違いだ。この記事ではファイル・データベース・ユーザー管理の3層で掃除し、再発を防ぐまでの手順を詳しく解説する。

wp2shell 攻撃で何が起きているのか

wp2shell 攻撃で何が起きているのか

WordPress の REST Batch API は複数の REST API リクエストをまとめて送信できる機能だ。この脆弱性を突かれると、認証なしで SQL インジェクションを起こし、INTO OUTFILE 命令で PHP ファイルをサーバーに書き込める。書き込まれた PHP ファイルは Web シェルとして機能し、攻撃者が自由にコマンドを実行できるようになる。

さらに攻撃者はデータベースに直接アクセスできるため、パスワードのハッシュを盗んだり、自分自身に管理者権限を付与したりすることが可能だ。偽のプラグインを /wp-content/mu-plugins/ に仕込んで恒久的なバックドアにする手口も確認されている。

被害にあったサイトを完全に掃除する手順

被害にあったサイトを完全に掃除する手順

掃除は「ファイルの掃除」「ユーザーとセッションの掃除」「データベースの掃除」の3段階で進める。始める前に必ずファイルとデータベースの完全バックアップを取る。

ファイルシステムから Web シェルと偽プラグインを削除する

FTP クライアントや SSH でサーバーに接続し、まず /wp-content/cache/ ディレクトリを開く。キャッシュ系のディレクトリ(/cache//wpo-cache/ など)に不自然な英数字の羅列(e042u9xy9ra1.php のようなファイル名)があれば、それが Web シェルだ。すべて削除する。

次に /wp-content/mu-plugins/ を確認する。Must-Use プラグインは自動的に有効化されるため、攻撃者が好んで使う場所だ。身に覚えのないファイル(galex_patch.php など)があれば削除する。通常の /wp-content/plugins/ にも見慣れないプラグインが追加されていないか調べる。

STEP 1 FTP/SSH でサーバーに接続
STEP 2 /wp-content/cache/ 内の怪しい PHP ファイルを削除
STEP 3 /wp-content/mu-plugins/ の身に覚えのないファイルを削除
STEP 4 WordPress 本体を 6.9.5 または 7.0.2 以上に更新
STEP 5 wp-config.php に DISALLOW_FILE_EDIT / DISALLOW_FILE_MODS を追加

ファイルの掃除が終わったら、WordPress 本体をパッチ適用済みバージョン(6.9.5 または 7.0.2 以上)に更新する。この更新で Batch API の脆弱性自体が塞がる。

wp-config.php にファイル改変防止の定数を追加する

将来の攻撃に備え、管理画面からのファイル編集とプラグインのインストールを無効化する。FTP または SSH で wp-config.php を開き、以下の2行を追記する。

define( 'DISALLOW_FILE_EDIT', true );
define( 'DISALLOW_FILE_MODS', true );

DISALLOW_FILE_EDIT は管理画面の「テーマエディター」「プラグインエディター」を無効化する。DISALLOW_FILE_MODS は管理画面からのプラグイン追加や更新をブロックする。すでに侵入された後の対策ではなく、掃除が完了した後に再発を防ぐ設定だ。

ユーザーとパスワード、セッションの掃除

ユーザーとパスワード、セッションの掃除

攻撃者はデータベースに直接アクセスしていたため、パスワードのハッシュを抜き取った可能性が高い。管理者を含む全ユーザーのパスワードを変更する。WordPress 管理画面だけでなく、MySQL データベース自体のパスワードも変更し、wp-config.phpDB_PASSWORD を新しいものに書き換える。

パスワード変更だけでは不十分だ。攻撃者がまだログインしたままかもしれない。全セッションを強制的に切断するには、Salt Keys(ソルトキー)を再生成して wp-config.php に上書きする。WordPress 公式の Salt Keys ジェネレーターで新しいキーセットを取得し、既存のキーと置き換えれば全デバイスのログイン状態が即座に無効になる。

最後に、管理画面の「ユーザー」一覧を開き、見覚えのない管理者アカウントが作られていないか確認する。もし存在すれば即座に削除する。

データベースに残った偽のレコードを削除する

データベースに残った偽のレコードを削除する

wp2shell 攻撃は、WordPress のセキュリティフィルターをすり抜けるために、データベース上に偽のナビゲーションメニュー項目と changeset(カスタマイザーの変更履歴)を一時的に生成する。これらのレコードは post_date2020-01-01 00:00:00 に固定されており、URL ペイロードに example.invalid を含むという特徴がある。

以下の SQL を phpMyAdmin などで実行する。なお、接頭辞(プレフィックス)がデフォルトの wp_ ではない場合は、コード内の wp_ を実際のプレフィックス(例: wp2_mysite_)に置き換える必要がある。

偽の changeset を削除する

DELETE FROM wp_posts WHERE post_type = 'customize_changeset' AND post_date = '2020-01-01 00:00:00';

偽のナビゲーションメニュー項目を削除する

DELETE FROM wp_posts WHERE post_type = 'nav_menu_item' AND post_date = '2020-01-01 00:00:00';

悪意のあるメタデータを削除する

DELETE FROM wp_postmeta WHERE meta_value LIKE '%example.invalid%';

これらのクエリでデータベース上の痕跡を一掃できる。実行前には必ずデータベースのバックアップを取る。

データベースユーザーから FILE 権限を剥奪する

データベースユーザーから FILE 権限を剥奪する

今回の攻撃は SQL インジェクション経由で INTO OUTFILE 命令を使い、データベースからディスクにファイルを書き込んでいた。WordPress の通常動作に FILE 権限はまったく不要だ。この権限を WordPress のデータベースユーザーから剥奪しておけば、同種の攻撃が再び成功する可能性を大きく下げられる。

データベースに root 権限でログインし、以下の SQL を実行する。'wp_user_name'@'localhost' は実際の WordPress 用データベースユーザー名に置き換える。

REVOKE FILE ON *.* FROM 'wp_user_name'@'localhost';
FLUSH PRIVILEGES;

REVOKE FILE は FILE 権限を取り消し、FLUSH PRIVILEGES は変更を即時反映する。これでデータベースからファイルシステムへの書き込み経路が遮断される。

Before FILE 権限あり
攻撃者 → SQL インジェクション → INTO OUTFILE → ディスクに PHP ファイル書き込み
After FILE 権限なし
攻撃者 → SQL インジェクション → INTO OUTFILE権限エラーで書き込み失敗
権限あり(攻撃経路あり)  権限剥奪後(経路遮断)

よくある質問

WordPress を更新しただけで掃除は不要か

更新だけでは不十分だ。攻撃者はすでに Web シェルをサーバーに書き込んでおり、そのファイルは更新では削除されない。データベース内の偽レコードや不正な管理者アカウントも残ったままになる。必ずファイルとデータベースの両方を掃除する。

DISALLOW_FILE_MODS を設定すると管理画面からプラグインを追加できなくなるのか

そのとおりだ。DISALLOW_FILE_MODStrue にすると、管理画面からのプラグインのインストール・更新・削除、テーマのインストール・更新がすべてブロックされる。必要な更新は FTP や SSH 経由で手動で行う運用になるが、攻撃者が管理画面からファイルを改変する経路を完全に塞げる。

SQL クエリのプレフィックス wp_ を変更し忘れるとどうなるか

テーブルが存在しないというエラーが出るだけで、データが破壊されることはない。それでも、間違ったテーブルを操作しないよう実行前に必ず実際のプレフィックスを確認する。多くのレンタルサーバーではインストール時に自動生成された固有のプレフィックスが使われている。

FILE 権限を剥奪すると WordPress の動作に影響は出るか

WordPress の通常動作に FILE 権限は一切使われない。記事の投稿やプラグインの動作、データベースの読み書きに影響は出ないため、安全に剥奪できる。

この記事のポイント

  • WordPress 本体の更新だけではバックドアとデータベースの痕跡が残る
  • /wp-content/cache/ と /wp-content/mu-plugins/ の不審な PHP ファイルを削除する
  • 全ユーザーのパスワード変更と Salt Keys 再生成でセッションを強制切断する
  • データベースから post_date が 2020-01-01 の偽 changeset とメニュー項目を削除する
  • WordPress の DB ユーザーから FILE 権限を剥奪し INTO OUTFILE 経路を塞ぐ
WooCommerceバリエーション商品のカート追加で重大エラーが出る時の修正方法

WooCommerceバリエーション商品のカート追加で重大エラーが出る時の修正方法

WooCommerce のブロックベースカートでバリエーション商品を追加した際に「woo-min-max-quantity-step-control-single」プラグインが原因で「このサイトで重大なエラーが発生しました」と表示される場合、原因はプラグインが商品オブジェクトの取得失敗を考慮していないことだ。該当ファイルの PHP コードに数行の修正を加えればエラーを回避できる。

なぜブロックカートでバリエーション商品だけエラーになるのか

エラーログを確認すると、問題はプラグインの min-max-controller.php 872行目付近で発生している。この行では wc_get_product() で商品情報を取得した直後に ->get_id() を呼んでいるが、wc_get_product() は対象の商品が見つからなかった場合に false を返す。ブロックベースのカート(Store API)経由でバリエーション商品が追加されると、この関数がまれに false を返す状況が発生する。プラグインのコードはその可能性をまったく想定しておらず、結果として「Call to a member function get_id() on false」という致命的な PHP エラーに直結している。

エラーを根本解決するためのコード修正手順

エラーを根本解決するためのコード修正手順
STEP 1 FTP や管理画面から該当ファイルを探す
STEP 2 872 行目付近のコードを確認し false チェックを追加する
STEP 3 修正したファイルをサーバーにアップロードする

該当ファイルを開き 872 行目周辺を特定する

FTP クライアント、またはレンタルサーバーのファイルマネージャーで、以下のパスにあるファイルを開く。WordPress 管理画面の「プラグイン」→「プラグインファイルエディター」から編集するのはできるだけ避ける。エディター画面で編集ミスをするとサイト全体が停止するリスクがあるためだ。

/wp-content/plugins/woo-min-max-quantity-step-control-single/includes/min-max-controller.php

使用しているエディタで行番号表示を有効にし、872 行目付近まで移動する。エラーログに表示されているとおり、->get_id() を直接呼んでいる箇所を探そう。

修正前と修正後のコードを比較する

修正前(エラー) Before
$product = wc_get_product( $product_id );
$min = $product->get_id();
修正後(安全) After
$product = wc_get_product( $product_id );
if ( ! $product || ! is_a( $product, ‘WC_Product’ ) ) {
    return;
}
$min = $product->get_id();
エラー状態  修正後

PHP コード修正の内容と意味

修正の核心は、$product が有効なオブジェクトかどうかを事前に検証することだ。

! $productwc_get_product()false を返した場合を検出する。is_a( $product, 'WC_Product' ) は、取得できたとしてもそれが WooCommerce の正規の商品オブジェクトであることを確認する。どちらかの条件を満たさなければ return で処理を中断し、以降の ->get_id() が呼ばれないようにする仕組みだ。

このガード節を入れることで、ブロックカート経由でどういった商品情報が渡ってきても、致命的なエラーにはならなくなる。

修正してもエラーが直らない場合の確認点

まれに、修正だけでは根本解決しないケースがある。以下の点も確認してみてほしい。

WooCommerce データベースのクリーンアップを実行する

「WooCommerce」→「ステータス」→「ツール」タブに移動し、「WooCommerce トランジェントをクリア」と「期限切れのトランジェントを削除」を実行する。キャッシュが原因で商品情報が正しく取得できていない場合に効果がある。

最小最大数量プラグインのバージョンと WooCommerce のバージョンを確認する

プラグインが最新の WooCommerce や Store API に対応していない可能性がある。プラグインの公式ページで対応バージョンを確認し、場合によっては別の数量制御プラグインを検討する必要がある。修正を加えても根本的な設計の問題で他の不具合が発生する場合は、開発者に修正リクエストを送りつつ、一時的に従来のショートコードカート([woocommerce_cart])へ切り戻すことも視野に入れる。

よくある質問

この問題はブロックカートだけに発生するのか

主にブロックベースのカートとチェックアウト(Store API)で発生する。従来のショートコードカートではエラーが出ないことも多いが、プラグインコードに潜在的な問題があるため、修正しておく方が安全だ。

プラグインがアップデートされたら修正は消えるか

消える。今回の修正はプラグインのコアファイルを直接編集しているため、プラグインにアップデートが配信されると編集内容は上書きされる。アップデート後に同様のエラーが再発した場合は、再び同じ手順で修正するか、開発者が修正を取り込むまでアップデートを控える必要がある。

子テーマの functions.php でこのエラーを回避できるか

難しい。今回のエラーはプラグイン内部の特定の行で発生しており、かつ商品取得のロジック周辺にフックが用意されていない限り、テーマファイル側から割り込んで防御することはできない。直接ファイルを編集する今回の方法が最も確実な対処法になる。

修正中にサイトが壊れてしまった場合の直し方は

FTP でサーバーにアクセスし、修正前にバックアップしておいた min-max-controller.php を上書きアップロードする。バックアップがない場合は、プラグインを一度削除して再インストールするのが早い。ただし、プラグインの設定内容はあらかじめメモしておく必要がある。

この記事のポイント

  • エラー原因はプラグイン内での get_id() 呼び出し前に false チェックがないこと
  • 修正対象は min-max-controller.php の 872 行目付近
  • wc_get_product()false を返す状況を考慮したガード節を追加する
  • ブロックカート(Store API)利用時に特に発生しやすい PHP エラーへの対処法
  • 直接ファイルを修正するため、プラグインのアップデートで編集が上書きされる点に注意
WordPressカスタムHTMLブロックが編集画面で消える原因と直し方

WordPressカスタムHTMLブロックが編集画面で消える原因と直し方

WordPress のブロックエディターでカスタム HTML ブロックを保存後に編集画面を開き直すと、ブロックの中身がまるごと消えて空欄に見える現象は、Gutenberg の React 側パーサーが HTML 構造を正しく解析できずに描画を放棄しているのが主な原因だ。script タグや閉じタグのない要素、複雑なインラインスタイルなどが引き金になる。

なぜカスタムHTMLブロックが編集画面で空になるのか

なぜカスタムHTMLブロックが編集画面で空になるのか

フロントエンドでは正しく表示されるのに、管理画面のブロックエディターだけで中身が空になるのは、データそのものはデータベースに保存されている証拠だ。コードエディターモードに切り替えれば、貼り付けた HTML が消えずに残っているのが確認できる。この現象が起こるのは、ブロックエディターがビジュアルモードでブロック内容を再表示するときに、DOM パーサーが特定の HTML を「壊れた構造」と判断してレンダリングを飛ばしてしまうからだ。

具体的には、Gutenberg が内部的に使用している React の DOM レンダリング機構が、管理画面の安全な枠組みの中で処理できないタグや構文に遭遇すると、そのブロック全体を安全のためにスキップする。結果として視覚的には空のブロックに見えるが、データベースの post_content には元のコードがそのまま格納されている。

カスタムHTMLブロックの中身が消える原因を特定する手順

カスタムHTMLブロックの中身が消える原因を特定する手順

まず、どの部分が問題を引き起こしているのかを切り分ける。以下の手順で原因箇所を絞り込む。

ブロックエディターのコードエディターモードで現状を確認する

編集画面右上の「︙」メニューから「コードエディター」を選択すると、ビジュアル表示ではなく生の HTML 構造が表示される。カスタムHTMLブロック内のコードがここで確認できれば、データは失われていない。このとき、Markdown 記法でブロック境界を示す <!-- wp:html --><!-- /wp:html --> のコメント行の内側にコードが残っているかを確かめる。

HTMLを最小単位に分解して原因のタグを特定する

ブロックに貼り付けた HTML を、1つのタグ単位で分割してカスタムHTMLブロックに1つずつ入れ直す。たとえば script タグ、style タグ、空要素(<div></div> など)、インラインイベントハンドラ(onclick など)をそれぞれ別のブロックに分けて保存し、再読み込み時に消えるかどうかをテストする。問題を起こすタグが特定できれば、その部分だけ別の実装方法に切り替えられる。

プラグイン競合の可能性を調べる

特定のプラグインがブロックエディターの動作に干渉して、カスタムHTMLブロックの描画を阻害しているケースもある。特にエディター拡張系のプラグインや、セキュリティ目的でスクリプトをフィルタリングするプラグインが入っている場合は、すべてのプラグインを一度無効化して標準テーマに切り替え、問題が再現するか確認する。プラグインが原因であれば、1つずつ再有効化して犯人を特定する。

カスタムHTMLブロックを正常に表示させる具体的な修正手順

カスタムHTMLブロックを正常に表示させる具体的な修正手順

原因が特定できたら、次は実際にブロックを正常に表示させる。script タグや複雑な HTML 構造が原因だった場合、以下のアプローチで回避できる。

STEP 1 原因となっているタグを特定する(script タグなど)
STEP 2 script タグはカスタムHTMLブロックの外に出す
STEP 3 複雑なHTMLはACFのフィールドやウィジェットで管理する
STEP 4 コードエディターモードで編集する運用に切り替える

script タグや iframe はカスタムHTMLブロックではなく適切な場所に配置する

Gutenberg のカスタムHTMLブロックは、セキュリティ上の理由から script タグの実行を制限している。また、ビジュアルエディターでの再レンダリング時に script タグを含むブロックを空として扱う挙動が確認されている。JavaScript を埋め込みたい場合は、カスタムHTMLブロックではなく、functions.php に wp_enqueue_script で登録するか、専用のコード埋め込みプラグインを使う。iframe も同様に、エディターのプレビューで空白になることがあるため、フロントエンドのみで描画される仕組みを検討する。

閉じタグのない空要素を見直す

カスタムHTMLブロックに <div></div> のような中身のない空タグや、閉じタグを省略した要素が含まれていると、Gutenberg のブロックパーサーが構造を正しく解釈できずにブロック全体をスキップすることがある。空の div や span は削除するか、&nbsp; を入れて実体を持たせる。とくに WordPress の自動整形機能(wpautop)が余分な p タグや br タグを挿入することで、意図しない空要素が生まれることもある。

複雑なHTML構造はカスタムフィールドやショートコードに置き換える

テーブルやフォーム、装飾を多用したマークアップは、カスタムHTMLブロック1つにまとめるよりも、ACF(Advanced Custom Fields)のテキストエリアフィールドや、ショートコード化して出力する方が安定する。とくにクライアントが自分で編集する前提のサイトでは、カスタムHTMLブロックを直接触らせると今回のようなトラブルが再発しやすい。テーマ側でテンプレートパーツとして管理し、投稿画面では入力欄だけを提供する設計が安全だ。

今後同様のトラブルを防ぐための運用ポイント

今後同様のトラブルを防ぐための運用ポイント

カスタムHTMLブロックに貼り付ける前にコード検証を行う

外部の HTML スニペットをそのまま貼り付ける前に、W3C のバリデーターや VSCode の構文チェック機能でタグの閉じ忘れや文法エラーがないかを確認する。コピー元の Web ページから取得したコードには、不要な属性や非推奨のタグが混じっていることが多い。貼り付け前に一度テキストエディターにペーストし、明らかな問題を取り除いてからブロックに入力する習慣をつける。

WordPress と Gutenberg を最新バージョンに保つ

Gutenberg プラグインを単体でインストールしている場合は、定期的に更新することでブロックパーサーの改善や既知の不具合修正が適用される。コア組み込みのブロックエディターであっても、WordPress 本体のアップデートによってパースエンジンの挙動が改良されることがある。編集画面でカスタムHTMLブロックが空になる現象の一部は、過去のバージョンで修正されたバグに起因している可能性もあるため、まずは最新の状態であることを確認する。

どうしても必要な場合はコードエディターモードを常用する

ビジュアルエディターで空になってしまう HTML をどうしてもページに残したいときは、編集時にコードエディターモードに切り替えて作業する方法が最終的な回避策になる。データベースにコードが正しく保存されているなら、コードエディター表示では常に中身が確認できる。手間は増えるが、複雑なマークアップや埋め込みコードを扱うページでは、あらかじめこの運用を前提にしておくとトラブルが起きても編集が止まらない。

よくある質問

カスタムHTMLブロックの中身は完全に消えたのか

ビジュアルエディターでは空に見えても、コードエディターモードに切り替えると HTML が残っていることがほとんどだ。データベースの post_content にも保存されているため、失われたわけではない。

プラグインをすべて無効化しても直らない場合はどうすればいいか

テーマの functions.php や使用中の子テーマがエディターの動作に干渉している可能性がある。標準テーマ(Twenty Twenty-Five など)に一時的に切り替えて再現するか確認し、テーマ側のフィルターやアクションを調査する。

script タグをカスタムHTMLブロックで使う正しい方法はあるか

原則としてカスタムHTMLブロック内の script タグは推奨されない。管理画面でのレンダリング問題に加え、セキュリティプラグインやサーバー側のフィルターで除去されるリスクもある。どうしても必要な場合はショートコード化するか、wp_enqueue_script でテーマに登録するのが安全だ。

ビジュアルエディターで空白になる特定の HTML タグの一覧はあるか

公式の一覧は存在しないが、script タグ、style タグ、iframe、object、embed、空の div や span、コメントアウト行、複雑に入れ子になったインラインスタイル付き要素などが報告されている。問題が起きたら該当タグを一つずつ検証するのが確実だ。

ビジュアルエディターで空になる現象は Gutenberg のバグなのか

仕様とバグの両面がある。script タグの実行制限はセキュリティ上の意図的な制限であり、空要素のパース失敗はブロックエディターの改善が期待される領域だ。WordPress コアのバージョンアップによって挙動が変わることもあるため、最新バージョンへの更新が有効な場合が多い。

この記事のポイント

  • カスタムHTMLブロックが空に見えてもデータはデータベースに残っている
  • script タグや空要素、閉じタグ省略がパース失敗の主原因
  • コードエディターモードで中身を確認し原因タグを特定する
  • 複雑な HTML はカスタムフィールドやショートコードで管理する
  • WordPress と Gutenberg の最新化で改善するケースがある
ハッキングされたWordPressサイトの完全復旧手順と再発防止策

ハッキングされたWordPressサイトの完全復旧手順と再発防止策

ハッキングされた WordPress サイトを復旧するには、マルウェアの削除だけでは不十分であり、SFTP や SSH といったホスティングレベルの認証情報をすべてローテーションし、バックドアを残さず完全に除去した上で、数週間にわたって再感染していないか監視を続ける必要がある。

WordPress がハッキングされる主な原因はどこにあるのか

WordPress がハッキングされる主な原因はどこにあるのか

侵入経路として圧倒的に多いのが、更新されていないプラグインやテーマの脆弱性だ。Patchstack の統計では、WordPress エコシステム全体の脆弱性の約96%がプラグイン、残り4%がテーマに存在し、コア本体に起因するものはごくわずかである。脆弱性が公表され修正パッチがリリースされると、攻撃者は数時間以内にそのバージョンを標的としたスキャンを開始する。

もう一つの主な侵入口は、弱いパスワードや使い回しの認証情報、あるいはフィッシング詐欺などで盗まれたログイン情報だ。攻撃者は WordPress の管理画面だけでなく、SFTP や SSH、ホスティングコントロールパネルといった上位のアクセス権も狙う。

侵入に成功した攻撃者は、すぐに目立った改ざんを行うとは限らない。ファイルに巧妙に偽装したバックドアを仕込み、追加の管理者アカウントを作成した後、数週間から数カ月潜伏するケースが一般的だ。そのため、サイト改ざんの直前に取得したバックアップであっても、見えないバックドアがすでに仕込まれている可能性を前提に復旧作業を進めなければならない。

侵入経路 脆弱性のあるプラグインやテーマ、盗まれた認証情報
潜伏行動 バックドアの設置、管理者アカウントの追加、SSH 鍵の登録
表面化 サイト改ざんやリダイレクト、検索結果の汚染など
攻撃者の動き 潜伏期間があるため、直近のバックアップも汚染されている可能性が高い

上図の流れが示すとおり、攻撃者はサイトに侵入したあと長期間潜伏し、ファイルやデータベースの奥深くに復旧を妨げる仕掛けを残す。

完全な掃除と再発防止のための5ステップ

完全な掃除と再発防止のための5ステップ

証拠を保全しログを収集する

復旧作業に着手する前に、改ざんされた状態のサイト全体(全ファイルとデータベースダンプ)のバックアップを取得し、証拠として安全な場所に保管する。ログの収集も同時に行う。利用しているサーバー会社へ、ウェブアクセスログ、SSH ログ、SFTP ログを依頼する。ログの保存期間はサーバー会社によって異なり、ウェブアクセスログは48時間程度、SFTP ログは提供されない場合もあるため、できるだけ早く依頼する必要がある。

解析ツールを使って感染範囲を特定する

取得したバックアップとログを解析する。AI を活用した解析ツールを使うと、大量のファイルからパターンを検出しやすい。もし感染前のクリーンなバックアップが存在するなら、それと比較することで未知のバックドアの発見率が大幅に上がる。スキャン範囲は wp-content ディレクトリ内だけに限定せず、ドキュメントルート全体とし、フォントファイルやキャッシュディレクトリに偽装されたシェルスクリプトも見落とさないようにする。

見つかったマルウェアと不正アカウントを削除する

検出された悪意のあるファイルは無効化ではなく削除する。単にプラグインを無効化しただけでは、該当ファイルに直接 URL でアクセスされると動作してしまう。また、管理画面のユーザー一覧に表示されない管理者アカウントや、データベースに直接埋め込まれた不正なエントリも除去する。

すべての認証情報をローテーションする

ファイルの掃除が完了しても、認証情報が漏洩したままだと再感染を繰り返す。WordPress のソルト(暗号化用の乱数文字列)とデータベースのパスワードを変更し、全ユーザーのパスワードをリセットする。さらに、SFTP のパスワード、SSH の公開鍵(身に覚えのない鍵はすべて削除)、API トークン、ホスティングのコントロールパネルのパスワードもすべて変更し、多要素認証を有効にする。作業に関わった全員が、自分のパソコンをマルウェアスキャンし、FTP クライアントにパスワードを保存する習慣をやめることも忘れてはならない。

WordPress 層 ソルトの変更、DBパスワードの変更、全ユーザーのパスワードリセット
ホスティング層 SFTP パスワードと SSH 鍵の変更、API トークンの再発行、コントロールパネルのMFA有効化
端末層 作業者のマルウェアスキャン、FTP クライアントからのパスワード削除
WordPress層 ホスティング層 端末層

この三層すべてで認証情報を更新しない限り、攻撃者は残った認証情報を使って何度でも侵入できる。

再感染の有無を監視し、クリーンな状態を維持する

一度の掃除で完全に除去できたと判断してはならない。掃除中に攻撃者が再侵入している可能性もあるため、作業が完了したら新しいバックアップとログを取得し、最初の解析ステップから再度実行する。このサイクルを、少なくとも二回連続で異常が検出されなくなるまで繰り返す。

本当にクリーンだと確信できるバックアップが取得できたら、それを信頼できるソース・オブ・トゥルース(基準点)として保管する。その後の定期バックアップはすべてこの基準点と比較し、差分が発生した瞬間を検知できるようにする。サイトが改ざんされる前に異常を捉えるには、復旧後も数週間は毎日バックアップとスキャンを継続し、問題がなければ監視頻度を徐々に落としていく方法が現実的だ。

アクセス権限を「必要性」で見直す

アクセス権限を「必要性」で見直す

WordPress の管理者アカウント、SFTP ユーザー、SSH 鍵、ホスティングのコントロールパネルユーザーは、それぞれが攻撃者にとっての侵入口になり得る。信頼できる人物であっても、その人が使うパソコンがマルウェアに感染したり、パスワードがフィッシング詐欺で盗まれたりすれば、そのアカウントは攻撃者に利用される。

そのため、アクセス権限は「信頼」ではなく「業務上の必要性」だけを基準に付与する。サイトの編集者に管理者権限は必要ないし、たまにコンテンツを修正するだけの担当者に SFTP アカウントは不要だ。経営者であっても、サーバーの操作が業務に含まれないならば管理者アクセスを持つべきではない。権限を持つアカウントの数を最小限に減らし、それぞれの権限レベルも必要最低限に絞ることが、最も低コストで効果的な防御策となる。

Before(信頼ベース) 編集者にも管理者権限 経営者にサーバー管理者権限 元スタッフのアカウントが残存
After(必要性ベース) 編集者は編集者権限 サーバー操作はエンジニアのみ 退職者のアカウントは即時削除

上記のように、権限を必要最低限に絞り込むだけで、攻撃者が悪用できる認証情報の総数は大幅に減る。

よくある質問

バックドアはどこに隠れていることが多いのか

wp-content 内のプラグインやテーマだけではなく、ドキュメントルート直下や、画像アップロードディレクトリ、キャッシュフォルダなどに偽装されるケースが多い。フォントファイル(.woff や .ttf)に偽装した悪意ある PHP コードが埋め込まれている事例もある。スキャンは必ずサイトのルート全体を対象にする必要がある。

データベースにもバックドアは残るのか

残る。管理画面のユーザー一覧に表示されない管理者アカウントや、プラグイン一覧から隠蔽された悪意あるプラグインのエントリがデータベースに直接書き込まれていることがある。ファイルの掃除だけでなく、データベースの直接確認も必須だ。

無料のセキュリティプラグインだけで復旧できるのか

セキュリティプラグインは感染の検知や予防には有効だが、すでに深く侵入されたサイトの完全な復旧を保証するものではない。特にホスティングレベルの認証情報が漏洩している場合、プラグインのスキャンでは検出できない経路から再侵入される。認証情報のローテーションと継続的なスキャンの組み合わせが不可欠になる。

復旧後、いつまで監視を続ければよいのか

少なくとも2週間は毎日のバックアップとスキャンを継続するのが現実的な目安だ。攻撃者が盗んだ認証情報をしばらく寝かせてから使うケースもあるため、数日間問題がなかったというだけで監視をやめてはいけない。2週間以上経過し、その間の全スキャンで異常がなければ、監視頻度を週に数回へ徐々に落としてもよい。

WP CLI を使わずに復旧作業は可能か

可能だが、手作業でのファイルの確認やデータベースの直接操作が必要になるため、作業時間と見落としのリスクが増加する。WP CLI に抵抗がある場合は、信頼できるエンジニアに依頼する方が安全だ。サーバー会社によっては、マルウェアスキャンと駆除の有償サービスを提供しているところもある。

この記事のポイント

  • ハッキングの侵入経路はプラグインやテーマの脆弱性、および漏洩した認証情報が大半を占める
  • バックドアはファイルとデータベースの両方に潜伏し、直近のバックアップも汚染されている前提で作業する
  • 復旧にはファイル削除と同時に、WordPress、ホスティング、作業端末の三層で認証情報のローテーションが必須
  • アクセス権限は「信頼」ではなく「必要性」で付与し、不要なアカウントは即座に削除する
  • 一度の掃除で完了とせず、数週間の継続監視と複数回のスキャンで再感染の有無を確認する
WooCommerce Taxが配送先住所を無視する原因と修正手順

WooCommerce Taxが配送先住所を無視する原因と修正手順

WooCommerceの自動税計算(WooCommerce Tax)が配送先住所を無視して店舗住所の税率を適用し続ける場合、設定のキャッシュか配送先住所の認識不良が原因だ。税計算の基準を再確認し、プラグインのトランジェントデータを手動で削除すれば、多くのケースで正しい税率に戻る。

配送先住所ではなく店舗住所の税率が使われる原因

配送先住所ではなく店舗住所の税率が使われる原因

WooCommerce Tax(旧称 WooCommerce Shipping & Tax)は、有効化すると TaxJar の自動税率データベースを参照して税額を算出する。管理画面の「WooCommerce > 設定 > 税」で「顧客の配送先住所に基づいて計算する」を選択しているにもかかわらず店舗住所の税率が使われるのは、次のいずれかが起きていると考えられる。

  • 税計算の基準設定が実際には店舗住所のまま保存されていない、または別のフィルターで上書きされている
  • プラグインが内部に保持するトランジェントキャッシュが古い設定を返し、配送先住所を無視している
  • チェックアウト時に配送先住所が正しくシステムに渡っていない(テーマや他のプラグインによる競合)
  • WooCommerce Tax が店舗の税ネクサス(課税拠点)を元にした「オリジンベース課税」のルールを配送先住所より優先してしまっている

特に最後の点は、米国のように州ごとにオリジンベース/デスティネーションベースの課税方式が異なる地域で混乱しやすい。日本国内のオンラインショップでは基本的に配送先住所の税率(消費税10%または軽減税率8%)が使われるべきだが、WooCommerce Tax が海外の課税ロジックを引きずっている場合もあり、実際に「店舗住所を変えると税率が変わってしまう」といった現象が報告されている。

誤った動き
配送先住所「大阪市 530-0001」(税率8.25%のはず)

適用される税率 → 店舗住所「東京都 100-0001」の税率10%
正しい動き
配送先住所「大阪市 530-0001」

適用される税率 → 配送先住所の8.25%
誤った状態  修正後

このデモのように、配送先住所を正しく入力していても、店舗住所の税率だけが繰り返し使われるのが典型的な症状だ。

税計算の基準が本当に配送先住所になっているか再確認する

税計算の基準が本当に配送先住所になっているか再確認する

まず根本的な設定ミスがないか、管理画面をチェックする。

STEP 1 WooCommerce > 設定 > 税 を開く
STEP 2 「配送先住所に基づいて計算する」が選択されているか確認
STEP 3 「自動税計算を有効にする」のチェックを一時的に外して保存し、再度チェックを入れて保存

設定画面上は正しく見えていても、内部的に値がロックされている場合がある。STEP 3 のように一度無効化して再保存することで、WooCommerce Tax の内部キャッシュをリセットできる。

トランジェントキャッシュを手動で削除する

WooCommerce Tax は API から取得した税率データを WordPress のトランジェント(一時キャッシュ)に保存している。このキャッシュが古いままだと、配送先住所が変わっても最初に引いた店舗住所のレートを返し続けることがある。

データベースを直接操作せずにキャッシュをクリアする方法

  • WooCommerce > ステータス > ツール に移動する
  • 「WooCommerce トランジェントをクリア」を実行する
  • さらに「顧客セッションをクリア」も実施する
  • 必要に応じて、WooCommerce Tax プラグインを無効化してから削除し、再度インストールして有効化する

再インストール時には、プラグインが新しい API キーを取得し、税設定が初期化される。その後、必ず「WooCommerce > 設定 > 税」で「配送先住所に基づいて計算する」を再設定する。

配送先住所の受け渡しをデバッグモードで検証する

配送先住所の受け渡しをデバッグモードで検証する

テーマや他のプラグインの影響で、チェックアウト画面から正しい配送先住所が WooCommerce Tax に渡っていない可能性もある。WooCommerce のデバッグモードを有効にして、税計算の内部ログを確認する。

設定 wp-config.php に define('WP_DEBUG', true); を追加
確認 チェックアウト時にデバッグログを Watch
調査 TaxJar API へのリクエストに正しい配送先 ZIP が渡っているか確認

WooCommerce > ステータス > ログ に、woocommerce-taxtaxjar のログファイルが生成される。配送先住所ではなく店舗住所が送信されているようであれば、テーマの functions.php やカスタムコードが住所情報を改変していないか精査する。

応急的に店舗住所を「配送先住所」と同じ扱いにするフィルター

どうしても自動税計算が配送先住所を認識せず、緊急で正しい税率を適用しなければならない場合、WordPress のフィルターフックを使って一時的に配送先住所を強制的に税計算に使わせることもできる。

add_filter( 'woocommerce_tax_based_on', function( $base ) {
    if ( is_checkout() || is_cart() ) {
        return 'shipping';
    }
    return $base;
});

このコードを子テーマの functions.php に追加すれば、カート・チェックアウト画面では常に配送先住所ベースの計算が強制される。ただし、根本原因の解決にはならないため、あくまで応急策として利用する。

よくある質問

よくある質問

WooCommerce Tax を再インストールしても直らないのはなぜか

再インストールだけでは、データベースに残ったトランジェントや設定値が削除されないことがある。プラグインを削除した後に「WooCommerce > ステータス > ツール」からトランジェントを完全クリアし、その上で再インストールする必要がある。

配送先住所が正しく入力されているのに税率が変わらないのはどうしてか

WooCommerce Tax は TaxJar API に配送先の ZIP コードと国・州の情報を送り、税率を取得する。このとき、ZIP コードが実在しないか API が認識できない場合、フォールバックとして店舗住所の税率を返す仕様がある。テストする住所が実在するか、郵便番号のフォーマットが正しいかを再確認する。

WooCommerce Tax を使わずに日本国内の税率を正確に計算するにはどうすればよいか

日本国内のオンラインショップで消費税のみを扱うなら、自動税率プラグインを無効化し、WooCommerce 標準の税率設定で「標準税率(10%)」と「軽減税率(8%)」を手動で登録する方が安定する。配送先住所の県や市町村による税率差分が不要なケースが大半のため、あえて自動計算を導入する必要はない。

テスト注文を何度も行っても税額が変わらない場合の最終確認事項は

テスト注文時には、必ずブラウザのシークレットウィンドウを使い、サイトのキャッシュやセッションの影響を排除する。また、カートの計算がセッション情報に依存するため、住所を変えるたびにカートを空にしてから再度商品を追加する。

特定の州や地域でオリジンベース課税のせいで税率が店舗住所になることはあるのか

米国の一部の州では、店舗所在地と配送先の両方が同じ州内にある場合、店舗所在地の税率を適用するオリジンベース課税が採用されている。しかし、WooCommerce Tax は州ごとの課税方式を自動で判別するわけではなく、設定上のトラブルでこの現象が起こることがある。日本のショップでは関係ないが、海外向けに販売する場合は注意が必要だ。

この記事のポイント

  • 自動税計算が配送先住所を無視するのは、設定キャッシュか住所の受け渡し不良が主な原因
  • 「WooCommerce > 設定 > 税」の計算基準を再確認し、無効化→再有効化で内部リセットを試す
  • トランジェントキャッシュを手動クリアし、必要ならプラグインの再インストールを行う
  • デバッグログで TaxJar API へのリクエスト内容を検証する
  • 日本国内のみのショップなら自動税率をやめ、標準税率を手動設定する方が安定する