# 機能設計書 29-支払いコレクション管理

## 概要

本ドキュメントは、Medusaコマースプラットフォームにおける支払いコレクション（Payment Collection）の管理機能について記載する。

### 本機能の処理概要

本機能は、注文やカートに関連する支払いを一元管理する支払いコレクションの作成・取得・更新・削除を行う機能である。支払いコレクションは、複数の支払いセッションや支払いレコードを束ねる親エンティティとして機能し、支払いの全体的なステータス、合計金額、認可済み金額、キャプチャ済み金額、返金済み金額などを追跡する。

**業務上の目的・背景**：ECサイトにおいて、1つの注文に対して複数の支払い方法を組み合わせたり、部分的なキャプチャや返金を行うケースがある。支払いコレクションは、これらの複雑な支払いシナリオを統一的に管理し、支払いの全体像を把握できるようにする。また、チェックアウトプロセスと支払いプロセスを分離することで、柔軟な支払いフローを実現する。

**機能の利用シーン**：
- カートの支払いコレクションを作成する時
- 注文の支払いステータスを確認する時
- 支払いコレクションのステータスを更新する時
- 支払いコレクションを完了としてマークする時

**主要な処理内容**：
1. 支払いコレクションの新規作成
2. 支払いコレクションの取得（単一/一覧）
3. 支払いコレクションの更新
4. 支払いコレクションの削除
5. 支払いコレクションの完了処理
6. 認可/キャプチャ/返金金額の追跡

**関連システム・外部連携**：
- 支払いセッションモジュール: 個別の支払いセッション管理
- 支払いプロバイダー: Stripe、PayPal等の外部決済サービス
- カートモジュール: カートとの関連付け
- 注文モジュール: 注文との関連付け

**権限による制御**：Admin APIでは管理者が全ての支払いコレクションを管理可能。Store APIでは認証済み顧客が自身のカートに関連する支払いコレクションにアクセス可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 管理画面（注文詳細） | 主画面 | 支払いステータス確認、操作 |
| - | チェックアウト画面 | 主画面 | 支払いコレクション作成 |

## 機能種別

CRUD操作

## 入力仕様

### 入力パラメータ

#### 支払いコレクション作成

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| currency_code | string | Yes | 通貨コード | ISO 4217 |
| amount | BigNumber | Yes | 合計金額 | 0以上 |
| metadata | object | No | メタデータ | JSON形式 |

#### 支払いコレクション更新

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| id | string | Yes | 支払いコレクションID | 存在すること |
| status | PaymentCollectionStatus | No | ステータス | 有効な列挙値 |
| metadata | object | No | メタデータ | JSON形式 |

### 入力データソース

- Admin API: DELETE /admin/payment-collections/{id}（削除）
- Store API: POST /store/payment-collections（作成）
- 内部ワークフロー（カート・注文処理時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| payment_collection | PaymentCollectionDTO | 支払いコレクション情報 |
| payment_collection.id | string | 支払いコレクションID（pay_colプレフィックス） |
| payment_collection.currency_code | string | 通貨コード |
| payment_collection.amount | BigNumber | 合計金額 |
| payment_collection.authorized_amount | BigNumber | 認可済み金額 |
| payment_collection.captured_amount | BigNumber | キャプチャ済み金額 |
| payment_collection.refunded_amount | BigNumber | 返金済み金額 |
| payment_collection.status | PaymentCollectionStatus | ステータス |
| payment_collection.completed_at | DateTime | 完了日時 |
| payment_collection.payment_sessions | PaymentSessionDTO[] | 支払いセッション一覧 |
| payment_collection.payments | PaymentDTO[] | 支払いレコード一覧 |

### 出力先

- APIレスポンス（JSON形式）
- データベース（payment_collectionテーブル）

## 処理フロー

### 処理シーケンス（ステータス更新）

```
1. 支払いセッションの操作（認可、キャプチャ等）
   └─ 支払いプロバイダーへのリクエスト

2. maybeUpdatePaymentCollection_実行
   └─ 支払いコレクションの状態を再計算

3. 金額計算
   ├─ 認可済み金額の集計
   ├─ キャプチャ済み金額の集計
   └─ 返金済み金額の集計

4. ステータス判定
   ├─ セッションなし → NOT_PAID
   ├─ セッションあり、認可なし → AWAITING
   ├─ 部分認可 → PARTIALLY_AUTHORIZED
   ├─ 全額認可 → AUTHORIZED
   └─ 全額キャプチャ → COMPLETED

5. 支払いコレクション更新
   └─ paymentCollectionService_.updateで保存
```

### フローチャート

```mermaid
flowchart TD
    A[支払い操作発生] --> B[maybeUpdatePaymentCollection_]
    B --> C[金額集計]
    C --> D{セッションあり?}
    D -->|No| E[NOT_PAID]
    D -->|Yes| F{認可金額 > 0?}
    F -->|No| G[AWAITING]
    F -->|Yes| H{全額認可?}
    H -->|No| I[PARTIALLY_AUTHORIZED]
    H -->|Yes| J{全額キャプチャ?}
    J -->|No| K[AUTHORIZED]
    J -->|Yes| L[COMPLETED]
    E --> M[DB更新]
    G --> M
    I --> M
    K --> M
    L --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-29-01 | ステータス遷移 | NOT_PAID → AWAITING → PARTIALLY_AUTHORIZED/AUTHORIZED → COMPLETED | 支払い操作時 |
| BR-29-02 | 金額整合性 | authorized_amount ≦ amount | 常時 |
| BR-29-03 | キャプチャ上限 | captured_amount ≦ authorized_amount | キャプチャ時 |
| BR-29-04 | 返金上限 | refunded_amount ≦ captured_amount | 返金時 |
| BR-29-05 | 完了条件 | captured_amount ≧ amount で COMPLETED | キャプチャ完了時 |
| BR-29-06 | カスケード削除 | 削除時に支払いセッション、支払いレコードもカスケード削除 | 削除時 |

### 計算ロジック

```
■ 認可済み金額
authorized_amount = Σ(認可済みセッションのamount)

■ キャプチャ済み金額
captured_amount = Σ(全支払いのcaptures.amount)

■ 返金済み金額
refunded_amount = Σ(全支払いのrefunds.amount)

■ ステータス判定
- payment_sessions.length === 0 → NOT_PAID
- authorized_amount === 0 → AWAITING
- authorized_amount < amount → PARTIALLY_AUTHORIZED
- authorized_amount >= amount → AUTHORIZED
- captured_amount >= amount → COMPLETED
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 作成 | payment_collection | INSERT | コレクション作成 |
| 取得 | payment_collection | SELECT | コレクション取得（関連含む） |
| 更新 | payment_collection | UPDATE | ステータス、金額更新 |
| 削除 | payment_collection | DELETE（論理） | コレクション削除 |
| 関連削除 | payment_session | CASCADE DELETE | セッションのカスケード削除 |
| 関連削除 | payment | CASCADE DELETE | 支払いレコードのカスケード削除 |

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

#### payment_collection

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT/UPDATE | id | 自動生成（pay_colプレフィックス） | 主キー |
| INSERT/UPDATE | currency_code | 通貨コード | 必須 |
| INSERT/UPDATE | amount | 合計金額 | BigNumber |
| INSERT/UPDATE | authorized_amount | 認可済み金額 | NULL許可 |
| INSERT/UPDATE | captured_amount | キャプチャ済み金額 | NULL許可 |
| INSERT/UPDATE | refunded_amount | 返金済み金額 | NULL許可 |
| INSERT/UPDATE | completed_at | 完了日時 | NULL許可 |
| INSERT/UPDATE | status | ステータス | 列挙型 |
| INSERT/UPDATE | metadata | メタデータ | JSON形式 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NOT_FOUND | MedusaError | 支払いコレクションが存在しない | 有効なIDを指定 |
| INVALID_DATA | MedusaError | 無効な通貨コード | 有効なISO 4217コードを指定 |
| INVALID_DATA | MedusaError | 金額が負の値 | 0以上の値を指定 |

### リトライ仕様

データベース接続エラー時は自動リトライが行われる場合がある。

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

- 支払いコレクションの更新と関連エンティティの更新は同一トランザクション内
- エラー発生時はロールバック

## パフォーマンス要件

- 単一取得: 300ms以内
- 更新: 500ms以内（外部プロバイダー呼び出しを除く）

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

- 支払い関連情報は機密情報として適切に保護
- Admin APIは認証必須
- Store APIでは自身の支払いコレクションのみアクセス可能

## 備考

- PaymentCollectionStatus列挙型: NOT_PAID, AWAITING, PARTIALLY_AUTHORIZED, AUTHORIZED, COMPLETED
- BigNumber型は精度の高い金額計算に使用される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | payment-collection.ts | `packages/modules/payment/src/models/payment-collection.ts` | 支払いコレクションモデル定義 |

**主要処理フロー（payment-collection.ts）**:
- **6-33行目**: PaymentCollectionモデル定義
- **8行目**: IDプレフィックスはpay_col
- **9-14行目**: currency_code, amount, authorized_amount等の金額フィールド
- **15-17行目**: status（列挙型）、デフォルトNOT_PAID
- **19-27行目**: provider、sessions、paymentsとの関連
- **29-31行目**: cascades - 削除時にsessions、paymentsをカスケード削除

#### Step 2: サービス層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | payment-module.ts | `packages/modules/payment/src/services/payment-module.ts` | 支払いモジュールサービス |

**主要処理フロー**:
- **176-204行目**: createPaymentCollections - コレクション作成
- **206-212行目**: createPaymentCollections_ - 内部実装
- **214-265行目**: updatePaymentCollections - コレクション更新
- **267-273行目**: updatePaymentCollections_ - 内部実装
- **954-1049行目**: maybeUpdatePaymentCollection_ - ステータス自動更新

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | route.ts | `packages/medusa/src/api/admin/payment-collections/[id]/route.ts` | Admin API削除 |

**主要処理フロー**:
- **8-23行目**: DELETE メソッド - 支払いコレクション削除

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

```
支払い操作（認可、キャプチャ等）
    │
    └─ maybeUpdatePaymentCollection_
           │
           ├─ paymentCollectionService_.retrieve (コレクション取得)
           │
           ├─ 金額集計
           │      ├─ authorized_amount計算
           │      ├─ captured_amount計算
           │      └─ refunded_amount計算
           │
           ├─ ステータス判定
           │
           └─ paymentCollectionService_.update (コレクション更新)
```

### データフロー図

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

支払いセッション操作 ───▶ maybeUpdatePaymentCollection_ ───▶ 更新後コレクション
                              │
                              ├─▶ セッション金額集計
                              │
                              ├─▶ キャプチャ金額集計
                              │
                              ├─▶ 返金金額集計
                              │
                              └─▶ ステータス更新 ───▶ payment_collection
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| payment-collection.ts | `packages/modules/payment/src/models/payment-collection.ts` | ソース | 支払いコレクションモデル |
| payment-module.ts | `packages/modules/payment/src/services/payment-module.ts` | ソース | 支払いモジュールサービス |
| route.ts | `packages/medusa/src/api/admin/payment-collections/[id]/route.ts` | ソース | Admin API |
