# 機能設計書 47-注文確認

## 概要

本ドキュメントは、チェックアウトプロセスにおける注文確認ページを表示する機能の設計を定義するものである。

### 本機能の処理概要

顧客が注文を確定する前に、注文内容、配送先、請求先、支払方法、配送方法を最終確認するためのページを表示する機能である。

**業務上の目的・背景**：注文確定前に顧客に最終確認の機会を提供することは、ECサイトにおいて法的にも業務的にも必要不可欠である。顧客は注文内容、金額、配送情報を確認し、誤りがないことを確認してから注文を確定できる。これにより、注文ミスによるキャンセルや返品を削減し、顧客満足度を向上させる。

**機能の利用シーン**：カートページから「レジに進む」をクリックし、ログイン/登録を完了した後に表示される。顧客はこのページで支払方法や配送方法を選択し、住所を確認・変更してから注文を確定する。

**主要な処理内容**：
1. 顧客のログイン状態を確認
2. カートに商品があることを確認
3. 利用可能な支払方法・配送方法を取得
4. 顧客の住所情報を検証
5. デジタル商品の有無に応じた撤回権表示の制御
6. ページデータを構築してテンプレートをレンダリング

**関連システム・外部連携**：支払方法ゲートウェイ、配送方法プロバイダー、住所検証システム

**権限による制御**：ログイン済み顧客のみがアクセス可能。ゲスト顧客はゲストチェックアウト登録後にアクセス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | 注文確認ページ | 主画面 | 注文内容の最終確認（CheckoutController::confirmPage） |
| 7 | カートページ | 遷移元 | レジに進むボタンからの遷移 |
| 11 | 注文完了ページ | 遷移先 | 注文確定後の遷移先 |

## 機能種別

画面表示 / データ取得 / バリデーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | URLパラメータは不要 | - |

### 入力データソース

- SalesChannelContext: リクエストから自動解決（顧客情報、支払/配送設定を含む）
- Cart: セッションまたは永続化ストレージから取得
- Request: HTTPリクエストオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| page | CheckoutConfirmPage | ページデータオブジェクト |
| page.cart | Cart | カート情報 |
| page.paymentMethods | PaymentMethodCollection | 利用可能な支払方法 |
| page.shippingMethods | ShippingMethodCollection | 利用可能な配送方法 |
| page.showRevocation | bool | 撤回権表示フラグ（デジタル商品用） |
| page.hideShippingAddress | bool | 配送先住所非表示フラグ |

### 出力先

- HTMLレスポンス（Twigテンプレートをレンダリング）

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ GETメソッドで /checkout/confirm にアクセス
2. 顧客認証チェック
   └─ context->getCustomer() で顧客ログイン確認
   └─ 未ログインの場合は登録ページへリダイレクト
3. カート内商品チェック
   └─ カートが空の場合はカートページへリダイレクト
4. ページデータ読み込み
   └─ CheckoutConfirmPageLoader::load() を呼び出し
5. 支払/配送方法取得
   └─ CheckoutGatewayRouteから利用可能なメソッドを取得
6. 住所検証
   └─ 請求先住所と配送先住所のバリデーション
7. デジタル商品チェック
   └─ カート内にデジタル商品があるか確認
   └─ 撤回権表示フラグと配送先住所非表示フラグを設定
8. フックイベント発火
   └─ CheckoutConfirmPageLoadedHook を発火
9. カートエラー処理
   └─ カートエラーがあればフラッシュメッセージに追加
10. ルートリロードチェック
    └─ 支払方法/配送方法変更エラーがあればリダイレクト
11. レスポンス返却
    └─ テンプレートをレンダリングして返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: confirmPage] --> B{顧客ログイン済み?}
    B -->|No| C[登録ページへリダイレクト]
    B -->|Yes| D{カートに商品あり?}
    D -->|No| E[カートページへリダイレクト]
    D -->|Yes| F[CheckoutConfirmPageLoader::load]
    F --> G[支払/配送方法取得]
    G --> H[住所検証]
    H --> I[デジタル商品チェック]
    I --> J[CheckoutConfirmPageLoadedHook発火]
    J --> K[カートエラー処理]
    K --> L{リロード必要?}
    L -->|Yes| M[同一ルートへリダイレクト]
    L -->|No| N[テンプレートレンダリング]
    C --> O[終了]
    E --> O
    M --> O
    N --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-47-01 | ログイン必須 | 注文確認ページへのアクセスにはログインが必要 | 常時 |
| BR-47-02 | カート必須 | カートに商品がない場合はアクセス不可 | 常時 |
| BR-47-03 | 撤回権表示 | デジタル商品がある場合は撤回権同意チェックを表示 | デジタル商品存在時 |
| BR-47-04 | 配送先非表示 | 物理的商品がない場合は配送先住所を非表示 | デジタル商品のみ時 |
| BR-47-05 | 住所検証 | 請求先・配送先住所の郵便番号形式を検証 | 住所設定時 |

### 計算ロジック

ページ読み込み時に以下が計算される：
- カート合計（StorefrontCartFacadeを経由）
- 利用可能な支払方法（条件に基づくフィルタリング）
- 利用可能な配送方法（条件に基づくフィルタリング）

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 支払方法取得 | payment_method | SELECT | 利用可能な支払方法を取得 |
| 配送方法取得 | shipping_method | SELECT | 利用可能な配送方法を取得 |
| カート取得 | cart | SELECT | カートデータを取得 |

### テーブル別操作詳細

このページは主に参照処理のため、データベースへの書き込みは発生しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 認証エラー | 顧客がログインしていない | 登録ページへリダイレクト |
| - | 業務エラー | カートが空 | カートページへリダイレクト |
| AddressValidationError | バリデーションエラー | 住所が無効 | カートエラーとして表示 |
| PaymentMethodChangedError | 業務エラー | 支払方法が利用不可になった | ページリロード |
| ShippingMethodChangedError | 業務エラー | 配送方法が利用不可になった | ページリロード |

### リトライ仕様

支払方法/配送方法の変更エラー時は、同一ページへのリダイレクトによる自動リロードが行われる。

## トランザクション仕様

参照処理のみのため、特別なトランザクション制御は不要。

## パフォーマンス要件

- レスポンス時間: 2000ms以内
- 複数のサービス呼び出しを含むため、他のページより処理時間が長い

## セキュリティ考慮事項

- ログイン認証必須
- CSRFトークン検証（フォーム送信時）
- robots noindex設定（検索エンジンからの非表示）
- キャッシュ無効化（PlatformRequest::ATTRIBUTE_NO_STORE）

## 備考

- 支払方法や配送方法の条件（最小注文額、特定商品など）はルールエンジンで評価される
- ヘッダーとフッターのPageletも別途読み込まれる

---

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

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

### 推奨読解順序

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

まず、ページオブジェクトの構造を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CheckoutConfirmPage.php | `src/Storefront/Page/Checkout/Confirm/CheckoutConfirmPage.php` | ページデータの構造 |

**読解のコツ**: CheckoutConfirmPageはPageを継承し、cart、paymentMethods、shippingMethods等のプロパティを持つ。

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

処理の起点となるコントローラーを特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CheckoutController.php | `src/Storefront/Controller/CheckoutController.php` | confirmPageメソッドがエントリーポイント |

**主要処理フロー**:
1. **117-160行目**: confirmPageメソッド全体
2. **126-128行目**: 顧客ログインチェック
3. **130-132行目**: カート空チェック
4. **134行目**: CheckoutConfirmPageLoader::load呼び出し
5. **138行目**: CheckoutConfirmPageLoadedHook発火
6. **140行目**: カートエラー処理
7. **142-150行目**: リロード判定とリダイレクト
8. **152-154行目**: ヘッダー/フッター読み込み
9. **155-159行目**: テンプレートレンダリング

#### Step 3: ページローダーを理解する

実際のデータ取得処理を行うページローダーを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CheckoutConfirmPageLoader.php | `src/Storefront/Page/Checkout/Confirm/CheckoutConfirmPageLoader.php` | データ取得ロジック |

**主要処理フロー**:
- **52-86行目**: load()メソッド全体
- **54-56行目**: 汎用ページローダーとメタ情報設定
- **58行目**: StorefrontCartFacade::getでカート取得
- **60行目**: CheckoutGatewayRouteで支払/配送方法取得
- **62-63行目**: 支払/配送方法をページに設定
- **65行目**: 住所検証
- **66行目**: カートをページに設定
- **68-76行目**: デジタル商品判定
- **78-79行目**: 撤回権表示フラグと配送先非表示フラグ設定
- **81-83行目**: イベント発火

#### Step 4: 住所検証を理解する

住所検証の詳細を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CheckoutConfirmPageLoader.php | `src/Storefront/Page/Checkout/Confirm/CheckoutConfirmPageLoader.php` | validateCustomerAddressesメソッド |

**主要処理フロー**:
- **99-111行目**: validateCustomerAddresses()メソッド
- **113-135行目**: validateBillingAddress()メソッド
- **137-163行目**: validateShippingAddress()メソッド

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

```
CheckoutController::confirmPage()
    │
    ├─ context->getCustomer() - ログインチェック
    │
    ├─ cartService->getCart() - カート空チェック
    │
    ├─ CheckoutConfirmPageLoader::load()
    │      │
    │      ├─ GenericPageLoader::load() - 基本ページ情報
    │      │
    │      ├─ setMetaInformation() - SEO情報設定
    │      │
    │      ├─ StorefrontCartFacade::get() - カート取得
    │      │
    │      ├─ CheckoutGatewayRoute::load() - 支払/配送方法取得
    │      │
    │      ├─ validateCustomerAddresses() - 住所検証
    │      │      │
    │      │      ├─ validateBillingAddress()
    │      │      │
    │      │      └─ validateShippingAddress()
    │      │
    │      └─ デジタル商品判定・フラグ設定
    │
    ├─ hook(CheckoutConfirmPageLoadedHook)
    │
    ├─ addCartErrors() - カートエラー処理
    │
    ├─ routeNeedsReload() - リロード判定
    │
    ├─ HeaderPageletLoader::load() - ヘッダー読み込み
    │
    ├─ FooterPageletLoader::load() - フッター読み込み
    │
    └─ renderStorefront() - テンプレートレンダリング
```

### データフロー図

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

SalesChannelContext ────▶ CheckoutController              ───▶ HTMLレスポンス
  │                              │                                    │
  ├─ Customer                    ▼                                    │
  │                      ログイン/カートチェック                       │
  │                              │                                    │
  │                              ▼                                    │
  │                      CheckoutConfirmPageLoader                    │
  │                              │                                    │
  │                              ▼                                    │
  ├─ Cart ───────────▶ StorefrontCartFacade                          │
  │                              │                                    │
  │                              ▼                                    │
  │                      CheckoutGatewayRoute                         │
  │                              │                                    │
  │                              ▼                                    ▼
  └─ Addresses ────────▶ 住所検証              ───────▶ CheckoutConfirmPage
                                 │                              │
                                 ▼                              ├─ cart
                         エラー/フラグ設定                       ├─ paymentMethods
                                                                ├─ shippingMethods
                                                                ├─ showRevocation
                                                                └─ hideShippingAddress
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CheckoutController.php | `src/Storefront/Controller/CheckoutController.php` | コントローラー | HTTPリクエスト処理 |
| CheckoutConfirmPageLoader.php | `src/Storefront/Page/Checkout/Confirm/CheckoutConfirmPageLoader.php` | ページローダー | データ取得・構築 |
| CheckoutConfirmPage.php | `src/Storefront/Page/Checkout/Confirm/CheckoutConfirmPage.php` | ページエンティティ | ページデータ構造 |
| StorefrontCartFacade.php | `src/Storefront/Checkout/Cart/SalesChannel/StorefrontCartFacade.php` | ファサード | カート取得 |
| AbstractCheckoutGatewayRoute.php | `src/Core/Checkout/Gateway/SalesChannel/AbstractCheckoutGatewayRoute.php` | ルート | 支払/配送方法取得 |
| GenericPageLoaderInterface.php | `src/Storefront/Page/GenericPageLoaderInterface.php` | インターフェース | 汎用ページ読み込み |
| CheckoutConfirmPageLoadedHook.php | `src/Storefront/Page/Checkout/Confirm/CheckoutConfirmPageLoadedHook.php` | フック | ページ読み込み後フック |
| index.html.twig | `src/Storefront/Resources/views/storefront/page/checkout/confirm/index.html.twig` | テンプレート | 画面レンダリング |
