# 機能設計書 52-寄付機能

## 概要

本ドキュメントは、Wikipedia iOSアプリにおけるWikimedia財団への寄付機能の設計を記述する。Apple PayとWebフォームの2種類の寄付方法をサポートし、複数の画面から寄付フローを開始できる。

### 本機能の処理概要

**業務上の目的・背景**：Wikimedia財団は非営利団体としてWikipediaを運営しており、その運営資金は主に寄付によって賄われている。モバイルアプリからの寄付機能を提供することで、ユーザーがより手軽にWikimediaの活動を支援できるようになる。Apple Payの統合により、ネイティブな決済体験を提供し、寄付の障壁を下げることを目的としている。

**機能の利用シーン**：ユーザーはプロファイル画面、設定画面、記事キャンペーンモーダル、Year in Review機能など様々な場所から寄付フローを開始できる。Apple Payが利用可能な場合はネイティブフォーム、そうでない場合はWebフォームが表示される。

**主要な処理内容**：
1. 寄付設定の取得（通貨、最低額、最高額等）
2. Apple Pay利用可否の判定
3. 支払い方法選択（Apple Pay / 他の方法）のアクションシート表示
4. Apple Payネイティブフォームまたは寄付Webビューの表示
5. 決済処理と成功時のサンキューメッセージ表示
6. 寄付完了時のログ記録

**関連システム・外部連携**：
- Wikimedia Payments Wiki API（支払い処理）
- Apple Pay / PassKit Framework
- WMFDonateDataController（寄付設定取得）

**権限による制御**：特別な権限は不要。Apple Pay利用には対応する支払いカードの設定が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | プロファイル画面各種 | 起点画面 | 寄付ボタンタップでフロー開始 |
| - | 設定画面 | 起点画面 | 寄付ボタンタップでフロー開始 |
| - | Year in Review画面 | 起点画面 | 寄付スライドからフロー開始 |

## 機能種別

外部API連携 / 決済処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source | DonateCoordinator.Source | Yes | 寄付開始元の識別 | 有効な列挙値 |
| navigationController | UINavigationController | Yes | ナビゲーションコントローラ | nil不可 |
| dataStore | MWKDataStore | Yes | データストア | nil不可 |
| theme | Theme | Yes | 現在のテーマ | nil不可 |
| navigationStyle | NavigationStyle | Yes | 画面遷移スタイル | 有効な列挙値 |

### 入力データソース

ユーザーのタップ操作（各画面の寄付ボタン）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| donationSuccess | Bool | 寄付成功フラグ |
| metricsID | String | ログ用のメトリクスID |

### 出力先

寄付フォーム画面、サンキュートースト通知

## 処理フロー

### 処理シーケンス

```
1. 寄付ボタンタップ
   └─ DonateCoordinator.start()が呼ばれる
2. 寄付設定の取得
   └─ WMFDonateDataController.fetchConfigsForCountryCode()
3. Apple Pay利用可否判定
   └─ PKPaymentAuthorizationController.canMakePayments()
4. 支払い方法選択シート表示
   └─ Apple Pay / 他の方法
5a. Apple Pay選択時
   └─ WMFDonateViewControllerを表示
5b. 他の方法選択時
   └─ SinglePageWebViewControllerで寄付ページを表示
6. 決済完了
   └─ サンキューメッセージ表示、ログ記録
```

### フローチャート

```mermaid
flowchart TD
    A[寄付ボタンタップ] --> B[寄付設定取得]
    B --> C{Apple Pay利用可能?}
    C -->|Yes| D[支払い方法選択シート]
    C -->|No| E[Webフォーム表示]
    D --> F{Apple Pay選択?}
    F -->|Yes| G[ネイティブ寄付フォーム]
    F -->|No| E
    G --> H[Apple Pay認証]
    H --> I{決済成功?}
    E --> J{Web決済完了?}
    I -->|Yes| K[サンキュートースト]
    I -->|No| L[エラー表示]
    J -->|Yes| K
    J -->|No| M[フォーム継続]
    K --> N[ログ記録]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-52-01 | 通貨別最低額 | 通貨ごとに最低寄付額が設定される | 寄付金額入力時 |
| BR-52-02 | 通貨別最高額 | 通貨ごとに最高寄付額が設定される | 寄付金額入力時 |
| BR-52-03 | 取引手数料オプション | 取引手数料を追加で寄付可能 | ネイティブフォーム |
| BR-52-04 | 月額継続寄付 | 月額継続寄付オプション | ネイティブフォーム |
| BR-52-05 | メール購読オプション | Wikimediaからのメール受信同意 | ネイティブフォーム |

### 計算ロジック

- 取引手数料: 寄付額に手数料率を乗じた額を追加

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | ローカルDBへの直接操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| invalidToken | トークンエラー | Apple Pay認証失敗 | エラーメッセージ表示 |
| missingDonorInfo | 入力エラー | 必須情報未入力 | フォームエラー表示 |
| validationAmountMinimum | バリデーション | 最低額未満 | 最低額メッセージ表示 |
| validationAmountMaximum | バリデーション | 最高額超過 | 最高額メッセージ表示 |
| paymentsWikiResponseError | API エラー | 決済API失敗 | エラーメッセージ表示 |

### リトライ仕様

ネットワークエラー時は再試行可能

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

Apple Pay決済はAppleのトランザクション管理に準拠

## パフォーマンス要件

寄付設定取得中はローディングインジケータを表示

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

- Apple Payによる安全な決済処理
- HTTPS通信の使用
- 決済情報はアプリに保存されない
- Merchant IDによる認証

## 備考

DonateCoordinatorは複数の画面から起動可能で、起動元に応じたメトリクスIDを生成する。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DonateCoordinator.Source | `Wikipedia/Code/DonateCoordinator.swift` | 寄付起点の列挙型 |
| 1-2 | NavigationStyle | `Wikipedia/Code/DonateCoordinator.swift` | 画面遷移スタイル |

**読解のコツ**: Sourceは記事キャンペーン、設定、プロファイル、Year in Review等を識別

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DonateCoordinator.swift | `Wikipedia/Code/DonateCoordinator.swift` | メインコーディネータ |

**主要処理フロー**:
1. **147-176行目**: start() - 寄付フロー開始
2. **180-317行目**: presentActionSheet() - 支払い方法選択
3. **319-414行目**: nativeDonateFormViewModel() - ネイティブフォームVM生成
4. **416-437行目**: navigateToNativeDonateForm() - ネイティブフォーム表示
5. **439-470行目**: navigateToOtherPaymentMethod() - Webフォーム表示

#### Step 3: 結果ハンドリングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DonateCoordinatorDelegate extension | `Wikipedia/Code/DonateCoordinator.swift` | 結果処理 |

**主要処理フロー**:
- **476-495行目**: handleDonateAction() - アクションハンドリング
- **546-574行目**: popAndShowSuccessToastFromNativeForm() - 成功トースト

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

```
ProfileCoordinator / SettingsViewController / YearInReviewCoordinator
    │
    └─ DonateCoordinator
           ├─ start()
           │      ├─ WMFDonateDataController.fetchConfigsForCountryCode()
           │      ├─ nativeDonateFormViewModel()
           │      │      └─ PKPaymentAuthorizationController.canMakePayments()
           │      └─ presentActionSheet()
           │
           ├─ navigateToNativeDonateForm()
           │      └─ WMFDonateViewController
           │             └─ Apple Pay処理
           │
           └─ navigateToOtherPaymentMethod()
                  └─ SinglePageWebViewController
                         └─ Webフォーム
```

### データフロー図

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

寄付ボタン ───▶ DonateCoordinator ───▶ WMFDonateDataController
タップ            │                          │
                 │                          ▼
                 │                   寄付設定データ
                 │                          │
                 ▼                          ▼
            支払い方法選択 ───▶ Apple Pay / Web Form
                                          │
                                          ▼
                               Payments Wiki API
                                          │
                                          ▼
                               サンキュートースト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| DonateCoordinator.swift | `Wikipedia/Code/` | ソース | 寄付フローの調整 |
| WMFDonateDataController | `WMFData/` | ソース | 寄付設定取得 |
| WMFDonateViewController | `WMFComponents/` | ソース | ネイティブ寄付フォーム |
| WMFDonateViewModel | `WMFComponents/` | ソース | 寄付フォームのビューモデル |
| DonateCoordinatorDelegate.swift | `WMFComponents/` | ソース | 寄付結果のデリゲート |
| DonateFunnel.swift | `Wikipedia/Code/` | ソース | アナリティクス記録 |
| SinglePageWebViewController.swift | `Wikipedia/Code/` | ソース | Web寄付フォーム表示 |
