# 通知設計書 19-Order Payment Method Changed

## 概要

本ドキュメントは、Shopwareにおける注文支払い方法変更通知（Order Payment Method Changed）の設計仕様を記載したものです。注文の支払い方法が変更された際に顧客に送信されるメール通知について定義します。

### 本通知の処理概要

この通知は、既存の注文に対して支払い方法が変更された際に発火するイベントです。顧客がマイアカウントから支払い方法を変更した場合や、管理者が手動で変更した場合に送信されます。

**業務上の目的・背景**：支払いに失敗した場合や、顧客が別の支払い方法を希望する場合に、支払い方法の変更が必要になることがあります。変更が行われた際に顧客に通知することで、変更内容の確認と、必要に応じたアクション（新しい支払い方法での決済完了等）を促すことができます。

**通知の送信タイミング**：`checkout.order.payment_method.changed`イベントがディスパッチされた際に、Flowビルダーで設定されたメール送信アクションがトリガーされます。

**通知の受信者**：注文を行った顧客のメールアドレス（`order.orderCustomer.email`）。

**通知内容の概要**：注文番号、変更後の支払い方法、決済トランザクション情報が含まれます。

**期待されるアクション**：顧客は新しい支払い方法を確認し、必要に応じて決済を完了します。

## 通知種別

メール通知（Flowで設定時のみ）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（Flow経由） |
| 優先度 | 高 |
| リトライ | Flowの設定に依存 |

### 送信先決定ロジック

イベント発生時に`MailRecipientStruct`が構築されます。

```php
// OrderPaymentMethodChangedEvent.php 行57-71
public function getMailStruct(): MailRecipientStruct
{
    if (!$this->mailRecipientStruct instanceof MailRecipientStruct) {
        $orderCustomer = $this->order->getOrderCustomer();
        if (!$orderCustomer) {
            throw OrderException::associationNotFound('orderCustomer');
        }

        $this->mailRecipientStruct = new MailRecipientStruct([
            $orderCustomer->getEmail() => $orderCustomer->getFirstName() . ' ' . $orderCustomer->getLastName(),
        ]);
    }

    return $this->mailRecipientStruct;
}
```

## 通知テンプレート

### メール通知の場合

| 項目 | 内容 |
|-----|------|
| 送信元アドレス | ショップ設定に依存 |
| 送信元名称 | ショップ設定に依存 |
| 件名 | カスタム設定（デフォルトテンプレートなし） |
| 形式 | HTML/テキスト |

### 本文テンプレート

デフォルトのメールテンプレートは提供されていません。Flowビルダーでメール送信アクションを設定する際に、カスタムテンプレートを作成する必要があります。

以下は推奨されるテンプレート例です：

**英語版（HTML）例**:
```html
<div style="font-family:arial; font-size:12px;">
    <p>
        {{order.orderCustomer.salutation.letterName }} {{order.orderCustomer.firstName}} {{order.orderCustomer.lastName}},<br/>
        <br/>
        The payment method for your order (Number: {{order.orderNumber}}) has been changed.<br/>
        <strong>New payment method: {{ orderTransaction.paymentMethod.name }}</strong><br/>
        <br/>
        If you need to complete the payment, please visit your account page.<br/>
        <br/>
        You can check the current status of your order anytime: {{ rawUrl('frontend.account.order.single.page', { 'deepLinkCode': order.deepLinkCode}, salesChannel.domains|first.url) }}
    </p>
</div>
```

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | 本通知には添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| `order` | 注文エンティティ | OrderEntity | Yes |
| `order.orderNumber` | 注文番号 | order.order_number | Yes |
| `order.orderCustomer` | 注文顧客情報 | order_customer | Yes |
| `order.deepLinkCode` | 注文詳細へのディープリンクコード | order.deep_link_code | Yes |
| `orderTransaction` | 決済トランザクション | OrderTransactionEntity | Yes |
| `orderTransaction.paymentMethod` | 新しい支払い方法 | payment_method | Yes |
| `orderTransaction.paymentMethod.name` | 支払い方法名 | payment_method_translation.name | Yes |
| `salesChannel` | 販売チャネル | - | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作/API | `checkout.order.payment_method.changed` | 支払い方法変更時 | ChangePaymentMethodRoute等から発火 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| Flowが設定されていない | Flowビルダーでメール送信アクションが設定されていない場合 |
| 注文顧客情報なし | orderCustomerがnullの場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[支払い方法変更リクエスト] --> B[ChangePaymentMethodRoute]
    B --> C[OrderTransactionの更新/作成]
    C --> D[OrderPaymentMethodChangedEvent発火]
    D --> E[Flowエンジンがイベントを検知]
    E --> F{Flowアクション設定あり?}
    F -->|あり| G[SendMailAction実行]
    F -->|なし| H[処理終了]
    G --> I[メール送信]
    I --> H
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| `order` | 注文基本情報 | 主要データソース |
| order_customer | 注文顧客情報 | メール宛先 |
| order_transaction | 決済トランザクション | 支払い方法情報 |
| payment_method | 支払い方法マスタ | 支払い方法名 |
| payment_method_translation | 支払い方法翻訳 | 多言語対応 |
| sales_channel | 販売チャネル | コンテキスト |

### テーブル別参照項目詳細

#### order

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | 注文識別 | イベントから取得 |
| order_number | 注文番号表示 | テンプレート変数 |
| deep_link_code | マイアカウントリンク | テンプレート変数 |

#### order_transaction

| 参照項目（カラム名） | 用途 | 取得条件 |
|-------------------|------|---------|
| id | トランザクション識別 | イベントから取得 |
| payment_method_id | 支払い方法 | JOIN payment_method |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| order_transaction | INSERT/UPDATE | 新しい支払い方法でトランザクション作成 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 注文顧客なし | orderCustomerがnull | OrderException::associationNotFound |
| メール送信失敗 | SMTPエラー等 | ログ記録、リトライ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | Flowの設定に依存 |
| リトライ間隔 | Flowの設定に依存 |
| リトライ対象エラー | 一時的なネットワークエラー |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | システム設定に依存 |
| 1日あたり上限 | システム設定に依存 |

### 配信時間帯

制限なし

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

- 支払い方法情報は機密性が高いため、適切な取り扱いが必要
- 決済関連の詳細情報（カード番号等）はテンプレートに含めない

## 備考

- このイベントは`OrderTransactionAware`インターフェースを実装しており、決済トランザクション情報にアクセス可能
- デフォルトのメールテンプレートは存在しないため、Flowで明示的にテンプレートを設定する必要がある
- 支払い方法変更後、顧客は新しい支払い方法で決済を完了する必要がある場合がある

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | OrderPaymentMethodChangedEvent.php | `src/Core/Checkout/Order/Event/OrderPaymentMethodChangedEvent.php` | イベントクラス、OrderTransactionAware実装 |
| 1-2 | OrderTransactionEntity.php | `src/Core/Checkout/Order/Aggregate/OrderTransaction/OrderTransactionEntity.php` | 決済トランザクションエンティティ |

**読解のコツ**: `OrderTransactionAware`インターフェースにより、決済トランザクション情報がFlowアクションで利用可能になる点に注目。

#### Step 2: イベント発火の仕組みを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | OrderActionController.php | `src/Core/Checkout/Order/Api/OrderActionController.php` | 管理画面からの変更時 |

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

```
支払い方法変更リクエスト
    │
    ▼
ChangePaymentMethodRoute / OrderActionController
    │
    ├─ OrderTransactionの作成/更新
    │
    └─ eventDispatcher->dispatch(OrderPaymentMethodChangedEvent)
           │
           └─ FlowExecutor (Subscriber)
                  │
                  └─ [設定されたアクション実行]
```

### データフロー図

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

支払い方法変更          ChangePaymentMethodRoute
リクエスト ────────────▶ OrderTransaction処理
                              │
                              ▼
                       OrderPaymentMethodChanged
                       Event発火
                              │
                              ▼
                       Flow Engine
                              │
                              ▼
                       [設定されたアクション]
                       (メール送信等)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| OrderPaymentMethodChangedEvent.php | `src/Core/Checkout/Order/Event/OrderPaymentMethodChangedEvent.php` | ソース | イベントクラス定義 |
| OrderTransactionEntity.php | `src/Core/Checkout/Order/Aggregate/OrderTransaction/OrderTransactionEntity.php` | ソース | 決済トランザクションエンティティ |
| SendMailAction.php | `src/Core/Content/Flow/Dispatching/Action/SendMailAction.php` | ソース | メール送信アクション |
