2026年10月4日

2026年10月4日

WooCommerceのチェックアウトに独自の入力欄を追加する方法|ブロック版とクラシック版

WooCommerce のチェックアウト(購入手続き)画面に、「配達についての希望」「当店を知ったきっかけ」のような独自の入力欄を足す方法は、チェックアウトのページがブロック版かクラシック版(ショートコード)かで違います。古い記事でよく紹介されている woocommerce_checkout_fields フィルターは、クラシック版でしか効きません。この記事では、まずどちらを使っているかを確かめ、それぞれのコードを紹介します(2026年10月時点の WooCommerce の開発者向けドキュメントに基づきます)。

コードは、子テーマの functions.php か、コードスニペット用のプラグインに追加します。本番に入れる前に、ステージング環境でテスト注文をして確かめてください。

どちらのチェックアウトを使っているかを確かめる

WooCommerce 8.3 以降を新しくインストールしたサイトでは、カートとチェックアウトのページはブロック版が既定です。それ以前から運用しているサイトは、クラシック版のままのことがあります。

  1. 管理画面の「WooCommerce」→「設定」を開き、「Advanced」タブ(日本語表示では訳語が異なることがあります)のページ設定で、チェックアウトページに指定されている固定ページを確認します。
  2. その固定ページをブロックエディターで開きます。
  3. 本文が「チェックアウト」ブロックならブロック版、ショートコード woocommerce_checkout が書かれていればクラシック版です。

ブロック版: Additional Checkout Fields API を使う

チェックアウトブロックでは、PHP で woocommerce_register_additional_checkout_field() を呼んで入力欄を登録します。登録した欄は、WooCommerce が画面への表示・入力値の保存を行います。登録は woocommerce_init アクション(またはそれより後)で行います。

<?php
/**
 * チェックアウトブロックに入力欄を2つ追加する。
 */
add_action( 'woocommerce_init', 'mysite_register_checkout_fields' );

function mysite_register_checkout_fields() {
	if ( ! function_exists( 'woocommerce_register_additional_checkout_field' ) ) {
		return;
	}

	// 1行の文字入力
	woocommerce_register_additional_checkout_field(
		array(
			'id'       => 'mysite/delivery-note',
			'label'    => '配達についての希望',
			'location' => 'order',
			'type'     => 'text',
			'required' => false,
		)
	);

	// 選択肢
	woocommerce_register_additional_checkout_field(
		array(
			'id'          => 'mysite/how-did-you-hear',
			'label'       => '当店を知ったきっかけ',
			'location'    => 'order',
			'type'        => 'select',
			'required'    => false,
			'placeholder' => '選んでください',
			'options'     => array(
				array( 'value' => 'search', 'label' => '検索エンジン' ),
				array( 'value' => 'sns', 'label' => 'SNS' ),
				array( 'value' => 'friend', 'label' => '知人の紹介' ),
			),
		)
	);
}

主な引数は次のとおりです。

引数 内容
id 名前空間/欄の名前 の形。他のプラグインと重ならない名前空間を付ける
label 画面に出す項目名
location 置く場所。contact(連絡先)、address(住所。請求先と配送先の両方に出る)、order(注文情報)
type text、select、checkbox、date
required 必須にするなら true
options select の選択肢。value と label の組を並べる

contact に置いた欄は、ログインしている顧客のアカウントにも保存され、「マイアカウント」の「アカウント詳細」で編集できます。address に置いた欄は、請求先と配送先のそれぞれに値が保存されます。

入力をチェックする

値の形式を確かめたい場合は、woocommerce_validate_additional_field アクションで WP_Error にエラーを追加します。エラーがあると、注文は確定せずに画面にメッセージが出ます。

<?php
add_action( 'woocommerce_validate_additional_field', 'mysite_validate_delivery_note', 10, 3 );

function mysite_validate_delivery_note( WP_Error $errors, $field_key, $field_value ) {
	if ( 'mysite/delivery-note' === $field_key && mb_strlen( (string) $field_value ) > 100 ) {
		$errors->add( 'mysite_delivery_note_too_long', '配達についての希望は100文字以内で入力してください。' );
	}
}

保存された値を読み出す

contact と order の欄は、注文のメタデータ _wc_other/ + id の名前(この例では _wc_other/mysite/delivery-note)に保存されます。読み出すときは、メタのキーを直接使うより、WooCommerce が用意している CheckoutFields の get_field_from_object() を使うことがドキュメントで推奨されています。

<?php
/**
 * 注文から「配達についての希望」を取り出す。
 */
function mysite_get_delivery_note( $order_id ) {
	$order = wc_get_order( $order_id );
	if ( ! $order ) {
		return '';
	}

	$checkout_fields = \Automattic\WooCommerce\Blocks\Package::container()->get(
		\Automattic\WooCommerce\Blocks\Domain\Services\CheckoutFields::class
	);

	// 3つ目の引数は、contact と order の欄なら 'other'、住所の欄なら 'billing' か 'shipping'
	return $checkout_fields->get_field_from_object( 'mysite/delivery-note', $order, 'other' );
}

登録した値が注文の詳細画面、注文完了画面、注文メールのどこに表示されるかは、WooCommerce のバージョンによって違うことがあります。テスト注文をして、管理画面の「WooCommerce」→「注文」で開いた注文と、届いたメールを確かめてください。

クラシック版(ショートコード): フックで追加する

チェックアウトのページがショートコードの場合は、次の4つのフックを組み合わせます。

  1. woocommerce_after_order_notes: 注文メモ欄の下に入力欄を出す
  2. woocommerce_checkout_process: 注文の送信時に値を確かめる
  3. woocommerce_checkout_update_order_meta: 注文に値を保存する
  4. woocommerce_admin_order_data_after_billing_address: 管理画面の注文詳細に表示する
<?php
// 1. 注文メモ欄の下に入力欄を出す
add_action( 'woocommerce_after_order_notes', 'mysite_classic_delivery_note_field' );

function mysite_classic_delivery_note_field( $checkout ) {
	woocommerce_form_field(
		'mysite_delivery_note',
		array(
			'type'        => 'text',
			'class'       => array( 'form-row-wide' ),
			'label'       => '配達についての希望',
			'placeholder' => '例: 午前中の配達を希望',
			'required'    => false,
		),
		$checkout->get_value( 'mysite_delivery_note' )
	);
}

// 2. 送信時に値を確かめる
add_action( 'woocommerce_checkout_process', 'mysite_classic_validate_delivery_note' );

function mysite_classic_validate_delivery_note() {
	$value = isset( $_POST['mysite_delivery_note'] ) ? sanitize_text_field( wp_unslash( $_POST['mysite_delivery_note'] ) ) : '';
	if ( mb_strlen( $value ) > 100 ) {
		wc_add_notice( '配達についての希望は100文字以内で入力してください。', 'error' );
	}
}

// 3. 注文に保存する(注文オブジェクト経由なので HPOS でも動く)
add_action( 'woocommerce_checkout_update_order_meta', 'mysite_classic_save_delivery_note' );

function mysite_classic_save_delivery_note( $order_id ) {
	if ( empty( $_POST['mysite_delivery_note'] ) ) {
		return;
	}
	$order = wc_get_order( $order_id );
	if ( ! $order ) {
		return;
	}
	$order->update_meta_data( '_mysite_delivery_note', sanitize_text_field( wp_unslash( $_POST['mysite_delivery_note'] ) ) );
	$order->save_meta_data();
}

// 4. 管理画面の注文詳細に表示する
add_action( 'woocommerce_admin_order_data_after_billing_address', 'mysite_classic_show_delivery_note', 10, 1 );

function mysite_classic_show_delivery_note( $order ) {
	$note = $order->get_meta( '_mysite_delivery_note' );
	if ( '' !== $note ) {
		echo '<p><strong>配達についての希望:</strong> ' . esc_html( $note ) . '</p>';
	}
}

注文の保存に update_post_meta() を使う古い例は、注文データを専用テーブルに保存する HPOS(高性能注文ストレージ)が有効なサイトでは動きません。上のように $order->update_meta_data() と save_meta_data() を使ってください。

注文メールにも載せる

クラシック版で追加した値を注文メールに載せるには、woocommerce_email_order_meta_fields フィルターに項目を足します。

<?php
add_filter( 'woocommerce_email_order_meta_fields', 'mysite_classic_delivery_note_email', 10, 3 );

function mysite_classic_delivery_note_email( $fields, $sent_to_admin, $order ) {
	$note = $order->get_meta( '_mysite_delivery_note' );
	if ( '' !== $note ) {
		$fields['mysite_delivery_note'] = array(
			'label' => '配達についての希望',
			'value' => $note,
		);
	}
	return $fields;
}

既存の項目を変える(クラシック版)

クラシック版では、woocommerce_checkout_fields フィルターで既存の項目を必須でなくしたり、消したりできます。

<?php
add_filter( 'woocommerce_checkout_fields', 'mysite_classic_adjust_fields' );

function mysite_classic_adjust_fields( $fields ) {
	// 電話番号を任意にする
	$fields['billing']['billing_phone']['required'] = false;
	// 会社名の欄を消す
	unset( $fields['billing']['billing_company'] );
	return $fields;
}

このフィルターはチェックアウトブロックには効きません。ブロック版で会社名・住所の2行目・電話番号の表示を変えたい場合は、チェックアウトのページをブロックエディターで開き、「チェックアウト」ブロックを選んだときの右側の設定を確認してください。

注意点

  • 入力値はそのまま信頼せず、保存前に sanitize_text_field() などで整え、表示するときは esc_html() でエスケープします。
  • 個人情報に当たる項目を増やす場合は、プライバシーポリシーの記載と、保存したデータの扱い(保存期間・削除の方法)も見直します。
  • 決済プラグインや配送プラグインの中には、チェックアウトの画面を独自に組み立てるものがあります。追加した欄が表示されない場合は、プラグインを止めた状態でも試し、どれが影響しているかを切り分けます。
  • コードを入れた後は、ログインした顧客とゲストの両方でテスト注文をし、入力欄の表示・入力チェック・注文詳細・メールへの反映を確かめます。

まとめ

  • まずチェックアウトのページがブロック版かクラシック版(ショートコード)かを確かめる
  • ブロック版は woocommerce_init で woocommerce_register_additional_checkout_field() を呼び、入力チェックは woocommerce_validate_additional_field で行う
  • クラシック版は woocommerce_after_order_notes・woocommerce_checkout_process・woocommerce_checkout_update_order_meta・woocommerce_admin_order_data_after_billing_address を組み合わせる
  • 注文への保存は update_post_meta() ではなく $order->update_meta_data() を使う

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲