# 画面設計書 9-チェックアウト登録ページ

## 概要

本ドキュメントは、Shopware 6 Storefrontにおけるチェックアウト登録ページの画面設計書である。未ログインユーザーがチェックアウトに進む際に、ゲスト購入または会員登録を行う画面である。

### 本画面の処理概要

チェックアウト登録ページは、カートに商品がある状態で未ログインユーザーがチェックアウトに進もうとした際に表示される画面である。既存会員のログイン、新規会員登録、ゲスト購入の3つの選択肢を提供する。

**業務上の目的・背景**：チェックアウト登録ページは、購入プロセスにおけるユーザー認証/登録の入口である。ECサイトにおいて「アカウント作成の強制」は購入離脱の大きな要因となるため、ゲスト購入オプションを提供することでコンバージョン率を向上させる。一方で、会員登録により顧客情報の蓄積、リピート購入の促進、マーケティング施策の展開が可能となるため、両方の選択肢を提示することが重要である。

**画面へのアクセス方法**：カートページから「注文手続きへ進む」をクリック（未ログイン時）、オフキャンバスカートから「チェックアウトへ」をクリック（未ログイン時）、URL直接アクセス（`/checkout/register`）でアクセスする。

**主要な操作・処理内容**：
1. 既存会員のログイン
2. 新規アカウントの作成
3. ゲスト購入（アカウント作成なし）
4. 住所情報の入力
5. 注文確認ページへの遷移

**画面遷移**：
- 遷移元：カートページ、オフキャンバスカート
- 遷移先：注文確認ページ（ログイン/登録成功後）、カートページ（カート空の場合）

**権限による表示制御**：未ログインユーザーのみアクセス可能。ログイン済みユーザーは注文確認ページへリダイレクトされる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | チェックアウト時登録 | 主機能 | ゲストまたは新規アカウントの登録（RegisterController::checkoutRegisterPage） |
| 7 | アカウント登録 | 補助機能 | 新規顧客アカウントの作成（RegisterController::register） |

## 画面種別

登録 / フォーム

## URL/ルーティング

| 項目 | 値 |
|------|-----|
| URL | `/checkout/register` |
| ルート名 | `frontend.checkout.register.page` |
| HTTPメソッド | GET |
| HTTPキャッシュ | 無効（_noStore） |
| SEO | 無効 |

## 入出力項目

### 入力項目（登録フォーム）

| 項目名 | パラメータ名 | 必須 | 型 | 説明 |
|--------|-------------|------|-----|------|
| 敬称 | salutationId | 必須 | string(UUID) | 敬称ID |
| 名 | firstName | 必須 | string | 名前 |
| 姓 | lastName | 必須 | string | 苗字 |
| メールアドレス | email | 必須 | string(email) | メールアドレス |
| パスワード | password | 条件付き | string | アカウント作成時のみ |
| 会社名 | company | 条件付き | string | 法人の場合 |
| 国 | countryId | 必須 | string(UUID) | 国ID |
| 州/県 | countryStateId | 条件付き | string(UUID) | 国設定による |
| 住所 | street | 必須 | string | 番地含む住所 |
| 郵便番号 | zipcode | 必須 | string | 郵便番号 |
| 市区町村 | city | 必須 | string | 市区町村名 |
| 電話番号 | phoneNumber | 設定による | string | 電話番号 |
| アカウント作成 | createCustomerAccount | 任意 | boolean | チェック時にアカウント作成 |
| 別の配送先 | differentShippingAddress | 任意 | boolean | 請求先と配送先が異なる場合 |

### 出力データ

| 項目名 | データソース | 説明 |
|--------|-------------|------|
| page | CheckoutRegisterPageLoader | ページ全体のデータオブジェクト |
| page.cart | カートサービス | カートオブジェクト |
| page.countries | 設定 | 利用可能な国一覧 |
| page.salutations | 設定 | 敬称一覧 |

## 表示項目

| セクション | 表示項目 | 説明 |
|-----------|---------|------|
| ヘッダー | ミニマルヘッダー | ロゴのみのシンプルヘッダー |
| メイン | ページタイトル | 「チェックアウト」 |
| メイン | ログイントグル | 「既にアカウントをお持ちですか？」リンク |
| ログイン | ログインフォーム | メールとパスワード入力 |
| 登録 | 個人情報フォーム | 敬称、名前、メールアドレス |
| 登録 | 住所フォーム | 国、住所、郵便番号、市区町村 |
| 登録 | アカウント作成オプション | パスワード設定 |
| 登録 | 配送先住所 | 別の配送先指定時に表示 |
| サイドバー | カートサマリー | 注文商品の概要 |
| サイドバー | 合計金額 | 小計、配送料、合計 |
| フッター | ミニマルフッター | 簡易フッター |

## イベント仕様

### 1-チェックアウト登録ページ表示

チェックアウト登録URLにアクセスすると、RegisterController::checkoutRegisterPageメソッドが実行される。

**処理フロー**：
1. ログイン済みの場合、注文確認ページへリダイレクト
2. カートが空の場合、カートページへリダイレクト
3. CheckoutRegisterPageLoaderでページデータを取得
4. CheckoutRegisterPageLoadedHookを発火
5. ヘッダー/フッターのPageletを取得
6. Twigテンプレートでレンダリング

### 2-ログインフォーム展開

「既にアカウントをお持ちですか？」をクリックすると、ログインフォームがcollapse展開される。

### 3-登録フォーム送信

登録フォームを送信すると、RegisterController::registerメソッドが実行される。

**エンドポイント**: `/account/register`
**ルート名**: `frontend.account.register.save`
**HTTPメソッド**: POST

**処理フロー**：
1. differentShippingAddressがfalseの場合、shippingAddressを削除
2. storefrontUrlを設定（ダブルオプトイン用）
3. アフィリエイトトラッキング情報を設定
4. guest属性を設定（createCustomerAccountの逆）
5. RegisterRouteで登録処理実行
6. ダブルオプトイン設定時は確認メール送信
7. 成功時は注文確認ページへリダイレクト

### 4-ログイン実行

ログインフォームを送信すると、AuthController::loginメソッドが実行される。

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| ページ表示 | country, salutation | SELECT | マスタデータ参照 |
| 会員登録 | customer, customer_address | INSERT | 顧客と住所の作成 |
| ゲスト登録 | customer, customer_address | INSERT | ゲスト顧客と住所の作成 |

### テーブル別更新項目詳細

#### customer（登録時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | email | フォーム入力値 | メールアドレス |
| INSERT | salutation_id | フォーム選択値 | 敬称 |
| INSERT | first_name | フォーム入力値 | 名 |
| INSERT | last_name | フォーム入力値 | 姓 |
| INSERT | password | ハッシュ化されたパスワード | アカウント作成時のみ |
| INSERT | guest | true/false | ゲスト購入フラグ |
| INSERT | sales_channel_id | 現在の販売チャネル | |

## メッセージ仕様

| メッセージ種別 | 条件 | メッセージ内容 |
|--------------|------|--------------|
| 成功 | ダブルオプトイン送信 | 「確認メールを送信しました」 |
| エラー | バリデーションエラー | 各フィールドのエラーメッセージ |
| エラー | メールアドレス重複 | 「このメールアドレスは既に使用されています」 |

## 例外処理

| 例外条件 | 対応 |
|---------|------|
| ログイン済み | 注文確認ページへリダイレクト |
| カート空 | カートページへリダイレクト |
| バリデーションエラー | フォームエラー表示（forwardToRoute） |

## 備考

- ヘッダーとフッターはミニマル版を使用（ナビゲーションなし）
- ダブルオプトイン設定は管理画面で制御可能
- パスワード確認フィールドの要否はシステム設定による
- メール確認フィールドの要否はシステム設定による
- アフィリエイトトラッキングコードはセッションから取得

---

## コードリーディングガイド

本画面を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CheckoutRegisterPage.php | `src/Storefront/Page/Checkout/Register/CheckoutRegisterPage.php` | ページオブジェクトの構造 |

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RegisterController.php | `src/Storefront/Controller/RegisterController.php` | checkoutRegisterPageメソッド（156-195行目） |

**主要処理フロー**:
1. **165-166行目**: リダイレクト先の設定（デフォルト: frontend.checkout.confirm.page）
2. **169-171行目**: ログイン済みの場合のリダイレクト
3. **173-175行目**: カート空の場合のリダイレクト
4. **177行目**: CheckoutRegisterPageLoaderでページデータ取得
5. **179行目**: CheckoutRegisterPageLoadedHookでフック処理
6. **181-182行目**: ヘッダー/フッターPagelet取得
7. **184-194行目**: テンプレートレンダリング

#### Step 3: 登録処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RegisterController.php | `src/Storefront/Controller/RegisterController.php` | registerメソッド（197-244行目） |

**主要処理フロー**:
- **205-207行目**: differentShippingAddressの処理
- **209-211行目**: storefrontUrl, affiliateTracking, guestの設定
- **213-223行目**: RegisterRouteの呼び出しとエラーハンドリング
- **225-232行目**: バリデーションエラー時のフォワード

#### Step 4: テンプレート構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | index.html.twig | `src/Storefront/Resources/views/storefront/page/checkout/address/index.html.twig` | メインテンプレート |
| 4-2 | register.html.twig | `src/Storefront/Resources/views/storefront/page/checkout/address/register.html.twig` | 登録フォーム |

### プログラム呼び出し階層図

```
RegisterController::checkoutRegisterPage()
    |
    +-- [ログイン済みチェック] -> リダイレクト
    |
    +-- [カート空チェック] -> リダイレクト
    |
    +-- CheckoutRegisterPageLoader::load()
    |       |
    |       +-- CartService::getCart()
    |       +-- CountryRoute::load()
    |       +-- SalutationRoute::load()
    |
    +-- CheckoutRegisterPageLoadedHook
    |
    +-- HeaderPageletLoader::load()
    +-- FooterPageletLoader::load()
    |
    +-- renderStorefront()
            +-- address/index.html.twig

RegisterController::register()
    |
    +-- prepareAffiliateTracking()
    |
    +-- RegisterRoute::register()
    |       |
    |       +-- customer INSERT
    |       +-- customer_address INSERT
    |
    +-- [ダブルオプトイン] -> 確認メール送信
    |
    +-- createActionResponse() -> リダイレクト
```

### データフロー図

```
[入力]                    [処理]                         [出力]

GET /checkout/register
        |
        v
RegisterController::checkoutRegisterPage()
        |
        +-- CheckoutRegisterPageLoader
        |
        v
CheckoutRegisterPage      -->  HTML Response
        |
        v
address/index.html.twig

POST /account/register
        |
        v
RegisterController::register()
        |
        v
RegisterRoute::register()
        |
        v
customer / customer_address  -->  Redirect
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| RegisterController.php | `src/Storefront/Controller/RegisterController.php` | コントローラー | ルーティングエントリーポイント |
| CheckoutRegisterPageLoader.php | `src/Storefront/Page/Checkout/Register/CheckoutRegisterPageLoader.php` | ページローダー | ページデータの構築 |
| CheckoutRegisterPage.php | `src/Storefront/Page/Checkout/Register/CheckoutRegisterPage.php` | データ構造 | ページオブジェクト定義 |
| index.html.twig | `src/Storefront/Resources/views/storefront/page/checkout/address/index.html.twig` | テンプレート | メインテンプレート |
| register.html.twig | `src/Storefront/Resources/views/storefront/page/checkout/address/register.html.twig` | テンプレート | 登録フォーム |
| login.html.twig | `src/Storefront/Resources/views/storefront/component/account/login.html.twig` | テンプレート | ログインフォーム |
| address-form.html.twig | `src/Storefront/Resources/views/storefront/component/address/address-form.html.twig` | テンプレート | 住所フォーム |
| header-minimal.html.twig | `src/Storefront/Resources/views/storefront/layout/header/header-minimal.html.twig` | テンプレート | ミニマルヘッダー |
