チェックアウトにフィールドを追加しても、画面に表示されるだけでは実装は完了していません。役立つフィールドにするには、具体的なニーズに応えること、サーバー側で検証すること、注文に紐付けて保存すること、必要とする担当者やプロセスに値を届けることが必要です。各段階で個別に問題が起こる可能性があります。
実装方法は、現在有効なチェックアウトのフローにも左右されます。クラシックチェックアウトのフックだけではCheckout Blockにフィールドを追加できません。コードを書く前に、ストアでどちらが使われているかを特定し、データの流れ全体を設計してください。
そのデータをチェックアウトで収集すべきか判断する

そのデータが必要な作業と、利用可能でなければならないタイミングを特定します。注文金額の計算、購入資格の判定、配送準備に不可欠であれば、購入確定前に収集する必要があるかもしれません。購入後の業務を円滑にするだけなら、不必要な手間を増やさないよう、購入後に収集することも検討してください。
目的、フィールドを利用する担当者、必須かどうか、保存期間を記録します。WooCommerceにその情報用の標準フィールドがすでにあるか確認してください。住所や電話番号を、どちらを優先するか決めずに重複して収集すると、データの不整合が生じます。機微なデータや影響の大きいデータについては、収集とアクセスを制限し、適用されるプライバシー上の義務を確認してください。
フローを特定してフィールドを追加する
購入手続きページで、従来型のショートコード[woocommerce_checkout]とCheckout Blockのどちらが使われているか確認します。そのページを変更するテンプレートや拡張機能も確認してください。見た目を判別するだけでは不十分です。拡張機能によってフローや処理が変更される場合があります。該当する仕組みを実装してテストし、一方のフロー向けに作成したフィールドがもう一方でも動くと決めつけないでください。
クラシックチェックアウト:フィールドと注文のフック
クラシックチェックアウトでは、woocommerce_checkout_fieldsでフィールドを変更し、woocommerce_after_checkout_validationで検証し、woocommerce_checkout_create_orderで注文の作成時に保存できます。次の例では、任意入力のフィールドを登録し、スカラー値以外の入力を拒否して、テキストをUnicode 120文字までに制限します。
add_filter('woocommerce_checkout_fields', function ($fields) {
$fields['order']['delivery_instructions'] = [
'type' => 'text',
'label' => '配送指示',
'required' => false,
'priority' => 25,
'maxlength' => 120,
'class' => ['form-row-wide'],
];
return $fields;
});
add_action('woocommerce_after_checkout_validation', function ($data, $errors) {
$raw = $data['delivery_instructions'] ?? '';
if (! is_scalar($raw)) {
$errors->add('delivery_instructions', '値はテキストで入力してください。');
return;
}
$value = trim(sanitize_text_field((string) $raw));
if (preg_match_all('/./us', $value, $matches) === false) {
$errors->add('delivery_instructions', 'テキストの形式が正しくありません。');
return;
}
if (count($matches[0]) > 120) {
$errors->add('delivery_instructions', 'テキストは120文字以内で入力してください。');
}
}, 10, 2);
add_action('woocommerce_checkout_create_order', function ($order, $data) {
$raw = $data['delivery_instructions'] ?? '';
if (! is_scalar($raw)) {
return;
}
$value = trim(sanitize_text_field((string) $raw));
if ($value !== '') {
$order->update_meta_data('_delivery_instructions', $value);
}
}, 10, 2);maxlength属性はブラウザー上の制約を設けるものであり、サーバー側の検証に代わるものではありません。この例はUTF-8対応の正規表現を使ってUnicodeコードポイントを数えます。一部の絵文字などは、ブラウザーではUTF-16コード単位を複数使用します。それらを許可する場合は、クライアント側とサーバー側で差が生じないよう、文字数のルールを明確に定めてテストしてください。
この例では、有効かつ空ではない値だけを保存します。フィールドを必須にする場合は、値がない場合も検証し、注文の作成前にエラーを返してください。内部名は安定したものを使い、既存データの移行を計画せずに変更しないでください。
Checkout Block:追加フィールドAPI
Checkout Blockでは、フォームにHTMLを挿入するのではなく、WooCommerceの追加チェックアウトフィールドAPIを使ってください。対応するプラグインまたはテーマから、たとえばwoocommerce_init中にフィールドを登録します。
add_action('woocommerce_init', function () {
if (! function_exists('woocommerce_register_additional_checkout_field')) {
return;
}
woocommerce_register_additional_checkout_field([
'id' => 'mi-plugin/delivery-instructions',
'label' => '配送指示',
'location' => 'order',
'type' => 'text',
'required' => false,
]);
});このAPIはフィールドをブロックのフローおよび注文への保存に統合します。個別のルールが必要な場合は、実際のインストール環境でAPIがサポートするサニタイズおよび検証オプションを確認し、エラーを含めてエンドツーエンドでテストしてください。正となるデータソースを決めずに、別の仕組みでも同じ値を保存しないでください。
デプロイ前に、登録関数が存在することを確認し、インストール済みバージョンに対応するドキュメントを参照してください。利用できない場合は、JavaScriptで互換性を装わないでください。更新するか、使用中のチェックアウトに対応した代替手段を選び、ステージング環境でテストしてください。
サーバー側で検証、正規化、保存する
ブラウザー側の検証はユーザー体験を向上させますが、セキュリティ対策にはなりません。必須項目の有無、型、長さ、形式、許可された選択肢に含まれることをサーバー側で確認してください。選択肢が固定されている場合は、クライアントから送られた任意のテキストではなく、既知の識別子を検証します。任意項目では、未入力と空文字列を同じ扱いにするか決めてください。値が無効な場合は、理解しやすいエラーを表示し、必要なデータを黙って無視して注文を確定しないでください。
クラシックフローの$order->update_meta_data()は注文のCRUD APIを使用するため、テーブルへの直接書き込みや特定のストレージ構造への依存を避けられます。Checkout Blockでは、追加フィールドAPIにフィールドの紐付けを任せ、注文APIまたは連携について文書化された仕組みで値を参照してください。内部メタデータキーを推測で決めつけないでください。
互換性を確認するには、WooCommerceの設定で、高パフォーマンス注文ストレージ(HPOS)と投稿テーブルベースのストレージのどちらが有効かを確認してください。同じ設定のテスト環境で各フローの注文を作成し、wc_get_order($order_id)を使ってWC_Orderオブジェクトとして読み込み、CRUD APIで値を確認します。たとえばクラシックフィールドなら$order->get_meta('_delivery_instructions')を使います。注文を更新して再度読み込み、内部テーブルへ直接SQLクエリを実行しないでください。ストレージの変更後や、チェックアウトに関わる拡張機能の更新後にも確認を繰り返してください。
管理画面で値を確認する
運用上の確認手順は、テスト注文を作成し、WooCommerce > 注文を開いて編集画面に入り、表示された値と送信値を照合することです。クラシックチェックアウトで、チームが使用する画面にメタデータが表示されない場合は、次の注文データフックを使って管理画面に表示を追加できます。
add_action('woocommerce_admin_order_data_after_billing_address', function ($order) {
$value = $order->get_meta('_delivery_instructions');
if ($value !== '') {
echo '<p><strong>配送指示:</strong> '
. esc_html($value) . '</p>';
}
});このフックと例のメタデータはクラシックチェックアウト用です。ストアで有効になっている管理画面での表示を確認してください。HPOSおよびブロックベースの注文編集画面では、実際の表示結果を確認します。クラシック画面向けの拡張機能が新しいインターフェースでも自動的に動くと想定しないでください。データの読み取りや編集には、必ず注文オブジェクトとCRUD APIを使ってください。
Checkout BlockのAPIで登録したフィールドは、注文の詳細に統合される場合があります。テスト注文を使ってWooCommerce > 注文で確認してください。別のコードから値を参照する必要がある場合は、インストール済みバージョンのAPIドキュメントで、フィールドの保存場所と読み取り方法を確認し、メタデータキーを推測しないでください。表示されない場合は、その画面に対応した管理画面表示を追加し、設定済みのストレージとインストール済みの管理機能拡張の両方でテストしてください。
編集が必要な場合は、許可するロールを定め、注文のCRUD APIを使って変更を保存してください。メール、書類、エクスポート、公開画面に値を自動表示しないでください。運用上の必要性がある場合にのみ各出力先へ追加し、アクセスを制限したうえで、出力を必ずエスケープしてください。
全工程をテストし、リグレッションを防ぐ
フィールドが表示されることだけを確認するテストでは不十分です。フォームから後続の利用までデータの流れを確認し、最低限、次の項目をテストしてください。
- 有効な注文で値を入力し、検証、正しい注文への保存、管理画面での確認を行う。
- 任意フィールドが空の場合と、必須フィールドが未入力の場合について、それぞれ定義した挙動を確認する。
- 改変された入力、スカラー値以外の入力、長すぎる入力、許可された選択肢にない入力が、サーバー側で拒否されることを確認する。
- アクセント記号やマルチバイト文字を含むテキストと、上限ちょうどの文字数をテストし、
maxlengthとの相互作用も確認する。 - 注文の更新後に何が変わるか、誰が変更できるか、変更がどのように反映されるかを確認する。
- クラシックチェックアウトとCheckout Blockをテストし、現在のフローと予定されているフロー変更の両方を確認する。
- 権限と公開範囲を確認し、許可されたユーザーとプロセスだけが値を受け取ることを確かめる。
合計金額、検証、注文作成のリグレッションテストも含めてください。自動処理がフィールドを利用する場合は、値がないときや送信に失敗したときの挙動もテストしてください。ブラウザーには値が表示されるのに、注文や利用予定のプロセスには表示されない場合は、問題を診断する明確な手がかりになります。
デプロイ前のチェックリスト

- データの目的と収集するタイミングを記録している。
- 有効なチェックアウトに合った仕組みを使用している。クラシックフローではフック、Blockでは追加フィールドAPIを使う。
- サーバー側で型、形式、長さを検証し、スカラー値以外の入力を拒否している。未入力、空、無効の扱いも定義している。
- インストール環境と注文ストレージを特定し、CRUD APIによる読み取りと更新をテストしている。
- テスト注文で、使用中の管理画面から値を確認でき、アクセスが制限されている。
- Unicode文字、更新、エラー、連携、チェックアウトのリグレッションをテストしている。



