# Connect の埋め込みコンポーネントの使用を開始する

ダッシュボードの機能をウェブサイトに埋め込む方法をご紹介します。

Connect の埋め込みコンポーネントを使用して、連結アカウントのダッシュボード機能をウェブサイトに追加します。これらのライブラリ、およびそのサポート API を使用することで、ダッシュボードやモバイルアプリケーションから Stripe プロダクトに直接アクセスできる許可をユーザーに付与できます。

- **統合 UI の追加**: 埋め込みコンポーネントを使用して、ダッシュボードに統合 UI を追加できます。[利用可能なすべてのコンポーネント](https://docs.stripe.com/connect/supported-embedded-components.md)をご覧ください。
- **外観のカスタマイズ**: ブランドに合わせて[外観](https://docs.stripe.com/connect/customize-connect-embedded-components.md)を調整できます。
- **常に最新の状態を維持**: Connect の埋め込みコンポーネントは Stripe API と同期しているため、実装を常に最新の状態に保てます。

## StripeConnect を設定する [クライアント側] [サーバー側]

Stripe は [AccountSession](https://docs.stripe.com/api/account_sessions.md) を使用して、API アクセスを連結アカウントに委任する意図を表します。

AccountSessions API は *client secret* (The client secret is a unique string returned from Stripe as part of an AccountSession. This string lets the client access a specific Stripe account with Connect embedded components) を返し、連結アカウントに対して API コールを行うときと同じように、埋め込みコンポーネントが連結アカウントのリソースにアクセスできるようにします。

### AccountSession を作成する (サーバー)

アカウントセッションを取得するために、アプリからサーバーへのリクエストを開始する必要があります。Client Secret をアプリに返すための新しいエンドポイントをサーバーに作成します。

#### Ruby

```ruby
require 'sinatra'
require 'stripe'
# This is a placeholder - it should be replaced with your API key.
# Sign in to see your own test API key embedded in code samples.
# Don't put any keys in code. We recommend using a restricted API key with access only to the account sessions resource. See https://docs.stripe.com/keys-best-practices
client = Stripe::StripeClient.new('<<YOUR_SECRET_KEY>>')

post '/account_session' do
  content_type 'application/json'

  # Create an AccountSession
  begin
    account_session = client.v1.account_sessions.create({
      account: {{CONNECTED_ACCOUNT_ID}},
      components: {
        account_onboarding: {
          enabled: true,
          features: {
            # We recommend disabling authentication for a better user experience when possible
            disable_stripe_user_authentication: true,
          }
        }
      }
    })

    {
      client_secret: account_session[:client_secret]
    }.to_json
  rescue => error
    puts "An error occurred when calling the Stripe API to create an account session: #{error.message}";
    return [500, { error: error.message }.to_json]
  end
end
```

### Create Account Session API

[ Account Session 作成 API](https://docs.stripe.com/api/account_sessions/create.md) によって、Connect 埋め込みコンポーネントでどのコンポーネントを表示し、どの機能へのアクセスを可能にするかが決定されます。Stripe はアカウントセッションに対応するすべてのコンポーネントにこれらのパラメーターを適用します。お客様のアプリが複数のユーザーの役割をサポートしている場合には、そのアカウントセッションで有効にされたコンポーネントと機能が現在のユーザーの役割に対応していることをご確認ください。 例えば、[返金の管理](https://docs.stripe.com/api/account_sessions/create.md#create_account_session-components-payments-features-refund_management)はお客様のサイトの管理者に対してのみ有効になり、他のユーザーはアクセスできません。ユーザーの役割へのアクセスを適用するには、サイトのユーザーの役割をアカウントセッションコンポーネントにマッピングする必要があります。

### StripeConnect SDK をインストールする (クライアント)

[Stripe iOS SDK](https://github.com/stripe/stripe-ios) はオープンソースです。[詳細なドキュメントが提供されており](https://stripe.dev/stripe-ios/index.html)、iOS 15 以降をサポートするアプリと互換性があります。

#### Swift Package Manager

SDK をインストールするには、以下のステップに従います。

1. Xcode で、**File (ファイル)** > **Add Package Dependencies… (パッケージ依存関係を追加)** を選択し、リポジトリー URL として `https://github.com/stripe/stripe-ios-spm` を入力します。
2. [リリースページ](https://github.com/stripe/stripe-ios/releases)から最新のバージョン番号を選択します。
3. **StripeConnect** 製品を[アプリのターゲット](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app)に追加します。

#### CocoaPods

1. まだインストールしていない場合は、[CocoaPods](https://guides.cocoapods.org/using/getting-started.html) の最新バージョンをインストールします。
2. 既存の [Podfile](https://guides.cocoapods.org/syntax/podfile.html) がない場合は、以下のコマンドを実行して作成します。
   ```bash
   pod init
   ```
3. この行を `Podfile` に追加します。
   ```podfile
   pod 'StripeConnect'
   ```
4. 以下のコマンドを実行します。
   ```bash
   pod install
   ```
5. これ以降は、Xcode でプロジェクトを開く際に、`.xcodeproj` ファイルではなく、必ず `.xcworkspace` ファイルを使用するということを忘れないでください。
6. 今後、SDK の最新バージョンに更新するには、以下を実行します。
   ```bash
   pod update StripeConnect
   ```

#### Carthage

1. まだインストールしていない場合は、[Carthage](https://github.com/Carthage/Carthage#installing-carthage) の最新バージョンをインストールします。
2. この行を `Cartfile` に追加します。
   ```cartfile
   github "stripe/stripe-ios"
   ```
3. [Carthage のインストール手順](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos)に従います。必ず、[こちら](https://github.com/stripe/stripe-ios/tree/master/StripeConnect#manual-linking)にリストされている必要なフレームワークのすべてを埋め込んでください。
4. 今後、SDK の最新バージョンに更新するには、以下のコマンドを実行します。
   ```bash
   carthage update stripe-ios --platform ios
   ```

#### 手動のフレームワーク

1. Stripe の [GitHub リリースページ](https://github.com/stripe/stripe-ios/releases/latest)に移動して、**Stripe.xcframework.zip** をダウンロードして解凍します。
2. **StripeConnect.xcframework** を、Xcode プロジェクトの **General (一般) ** 設定の **Embedded Binaries (埋め込みバイナリー)** セクションにドラッグします。**Copy items if needed (必要に応じてアイテムをコピーする)** を必ず選択してください。
3. [こちら](https://github.com/stripe/stripe-ios/tree/master/StripeConnect#manual-linking)にリストされている必要なフレームワークのすべてに対して、ステップ 2 を繰り返します。
4. 今後、Stripe の SDK の最新バージョンに更新するには、ステップ 1 から 3 を繰り返します。

> SDK の最新リリースおよび過去バージョンの詳細については、GitHub の [Releases (リリース)](https://github.com/stripe/stripe-ios/releases) ページをご覧ください。リポジトリの[リリースをウォッチ](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository)して、新しいリリースの公開時に通知を受け取ることも可能です。

### カメラ認証を設定する (クライアント側)

Stripe Connect iOS SDK では、本人確認書類をキャプチャーするためにデバイスのカメラにアクセスする必要があります。アプリからカメラへのアクセスの許可をリクエストできるようにするには、次の操作を行います。

1. Xcode で、プロジェクトの **Info.plist** を開きます。
2. `NSCameraUsageDescription` キーを追加します。
3. アプリにカメラへのアクセスの許可が必要な理由をユーザーに説明する文字列値を追加します。

> このアプリは、カメラを使用して本人確認書類の写真を撮影します。

カメラ認証のリクエストについて、詳細は [Apple のドキュメント](https://developer.apple.com/documentation/avfoundation/cameras_and_media_capture/requesting_authorization_for_media_capture_on_ios)を参照してください。

### EmbeddedComponentManager を初期化する (クライアント)

`StripeAPI.shared` を使用して公開可能キーを設定し、サーバー上に作成した新しいエンドポイントを呼び出してクライアントシークレットを取得するクロージャを持つ[ EmbeddedComponentManager](https://stripe.dev/stripe-ios/stripeconnect/documentation/stripeconnect/embeddedcomponentmanager) をインスタンス化します。コンポーネントを作成するには、上記でインスタンス化した `EmbeddedComponentManager` の適切な create メソッドを呼び出します。

[アカウントのユーザー登録](https://docs.stripe.com/connect/supported-embedded-components/account-onboarding.md) は、独自のプレゼンテーションを管理するコントローラを返します。[決済](https://docs.stripe.com/connect/supported-embedded-components/payments.md) のような他のコンポーネントは、より柔軟にアプリで表示できる [UIViewController](https://developer.apple.com/documentation/uikit/uiviewcontroller) を返します。

#### UIKit

```swift
import StripeConnect
import UIKit

class MyViewController: UIViewController {
    let errorView: UIView

    func fetchClientSecret() async -> String? {
        let url = URL(string: "https://{{YOUR_SERVER}}/account_session")!

        var request = URLRequest(url: url)
        request.httpMethod = "POST"

        do {
            // Fetch the AccountSession client secret
            let (data, _) = try await URLSession.shared.data(for: request)
            let json = try JSONSerialization.jsonObject(with: data) as? [String : Any]

            errorView.isHidden = true

            return json?["client_secret"] as? String
        } catch let error {
            // Handle errors on the client side here
            print("An error occurred: \(error)")
            errorView.isHidden = false
            return nil
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // This is your test publishable API key.
        STPAPIClient.shared.publishableKey = "{{PUBLISHABLE_KEY}}"
        let embeddedComponentManager = EmbeddedComponentManager(
            fetchClientSecret: fetchClientSecret
        )

        // Account onboarding presents modally and fullscreen
        let controller = embeddedComponentManager.createAccountOnboardingController()
        controller.title = "Onboard with Stripe"
        controller.present(from: self)

        // All other components can be flexibly presented
        let paymentsViewController = embeddedComponentManager.createPaymentsViewController()
        present(paymentsViewController)
    }
}
```

## Configure the Embedded Component Manager [クライアント側]

[参考資料 :external: をご覧ください](https://stripe.dev/stripe-ios/stripeconnect/documentation/stripeconnect/embeddedcomponentmanager/init(apiClient:appearance:fonts:fetchClientSecret:)。

### Connect 埋め込みコンポーネントのデザインをカスタマイズする

[埋め込みコンポーネント Figma UI ツールキット](https://www.figma.com/community/file/1438614134095442934)には、すべてのコンポーネント、一般的なパターン、サンプルアプリケーションが含まれています。これを使用して、ウェブサイトに埋め込まれた UI を可視化してデザインできます。

Stripe は、Connect 埋め込みコンポーネントのデザインをカスタマイズするための[一連のオプション](https://docs.stripe.com/connect/embedded-appearance-options.md)を提供しています。これらをカスタマイズすると、デザインシステムのボタン、アイコン、その他のアクセントに影響します。

> #### 必要なポップアップ
> 
> [ユーザー認証](https://docs.stripe.com/connect/get-started-connect-embedded-components.md#user-authentication-in-connect-embedded-components)などの埋め込みコンポーネントの一部の動作は、認証済みの WebView に表示する必要があります。埋め込みコンポーネントをカスタマイズして、これらの WebView を排除することはできません。

これらのオプションは、`EmbeddedComponentManager` を初期化するときに [EmbeddedComponentManager.Appearance](https://stripe.dev/stripe-ios/stripeconnect/documentation/stripeconnect/embeddedcomponentmanager/appearance) を使用して設定できます。

```swift
func fetchClientSecret() async -> String? {
    let url = URL(string: "https://{{YOUR_SERVER}}/account_session")!

    var request = URLRequest(url: url)
    request.httpMethod = "POST"

    do {
        let (data, _) = try await URLSession.shared.data(for: request)
        let json = try JSONSerialization.jsonObject(with: data) as? [String : Any]

        return json?["client_secret"] as? String
    } catch {
        return nil
    }
}

// Specify custom fonts
var customFonts: [CustomFontSource] = []
let myFont = UIFont(name: "My Font", size: 16)!
let fontUrl = Bundle.main.url(forResource: "my-font-2", withExtension: "woff")!
do {
    let customFontSource = try CustomFontSource(font: myFont, fileUrl: fontUrl)
    customFonts.append(customFontSource)
} catch {
    print("Error loading custom font: \(error)")
}

// Customize appearance
var appearance = EmbeddedComponentManager.Appearance()
appearance.typography.font.base = myFont
appearance.typography.fontSizeBase = 16 // Unscaled font size
appearance.colors.primary = UIColor { traitCollection in
    if traitCollection.userInterfaceStyle == .dark {
        return UIColor(red: 0.455, green: 0.424, blue: 1.000, alpha: 1.0)
    } else {
        return UIColor(red: 0.404, green: 0.365, blue: 1.000, alpha: 1.0)
    }
}

STPAPIClient.shared.publishableKey = "{{PUBLISHABLE_KEY}}"
let embeddedComponentManager = EmbeddedComponentManager(
    appearance: appearance,
    fonts: customFonts,
    fetchClientSecret: fetchClientSecret
)
```

[ダークモード](https://developer.apple.com/design/human-interface-guidelines/dark-mode)や[アクセシビリティコントラスト](https://developer.apple.com/documentation/uikit/uiaccessibilitycontrast)など、[ダイナミックプロバイダー](https://developer.apple.com/documentation/uikit/uicolor/3238041-init)を使用したデザインの色は、[UITraitCollection](https://developer.apple.com/documentation/uikit/uitraitcollection) が更新されたときに Connect 埋め込みコンポーネントに自動的に適用されます。デフォルトのデザインにはダークモードの色は含まれていないため、アプリでダークモードを対応するには、`EmbeddedComponentManager` にダイナミックカラーを使用したデザインを指定する必要があります。

フォントサイズを指定する場合は、デバイスのデフォルトサイズクラスに表示される、拡大縮小されていないフォントサイズを使用します。埋め込みコンポーネントは、[UITraitCollection](https://developer.apple.com/documentation/uikit/uitraitcollection) に基づいてフォントサイズを自動的に拡大縮小します。

 iOS のデザインオプションの[全リスト](https://docs.stripe.com/connect/embedded-appearance-options.md)をご覧ください。

### カスタムフォントを使用する

アプリでカスタムフォントを使用する場合 (例えばアプリバイナリに埋め込まれた `.otf` や `.tff` のファイルから)、`EmbeddedComponentManager` を初期化するときに `fonts` 引数に渡される [CustomFontSource](https://stripe.dev/stripe-ios/stripeconnect/documentation/stripeconnect/embeddedcomponentmanager/customfontsource) で、そのフォントファイルを指定する必要があります。これにより Connect 埋め込みコンポーネントからこれらのフォントファイルにアクセスできるようになり、フォントを適切にレンダリングできます。

`appearance` で指定されたフォントは、正しくレンダリングするために、初期化時に `EmbeddedComponentManager` に渡される[サポート対象のシステムフォント](https://developer.apple.com/fonts/system-fonts/)または [CustomFontSource](https://stripe.dev/stripe-ios/stripeconnect/documentation/stripeconnect/embeddedcomponentmanager/customfontsource) を使用する必要があります。

[参考資料 :external: をご覧ください](https://stripe.dev/stripe-ios/stripeconnect/documentation/stripeconnect/embeddedcomponentmanager/customfontsource)。

### 初期化後に Connect 埋め込みコンポーネントを更新する

`update` メソッドを呼び出して、初期化後に埋め込みコンポーネントのデザインを変更します。

```swift
var appearance = EmbeddedComponentManager.Appearance()
appearance.colors.primary = UIColor.red

manager.update(appearance: appearance)
```

## 認証

Stripe は、Connect 埋め込みコンポーネントでアカウントセッションとユーザー認証情報を管理するための一連の API を提供しています。

### Client Secret を更新する

長時間実行されるセッションでは、最初に提供された *Client Secret* (The client secret is a unique string returned from Stripe as part of an AccountSession. This string lets the client access a specific Stripe account with Connect embedded components) によるセッションが期限切れになることがあります。有効期限が切れると、Stripe は自動的に `fetchClientSecret` を使用して新しい Client Secret を取得し、セッションを更新します。貴社が追加のパラメーターを渡す必要はありません。

```swift
func fetchClientSecret() async -> String? {
    var request = URLRequest(url: URL(string: "https://{{YOUR_SERVER}}/account_session")!)
    request.httpMethod = "POST"

    do {
        let (data, _) = try await URLSession.shared.data(for: request)
        let json = try JSONSerialization.jsonObject(with: data) as? [String : Any]
        return json?["client_secret"] as? String
    } catch let error {
        return nil
    }
}

STPAPIClient.shared.publishableKey = "{{PUBLISHABLE_KEY}}"
let embeddedComponentManager = EmbeddedComponentManager(
    fetchClientSecret: fetchClientSecret
)
```

## 各地域への適応

Connect 埋め込みコンポーネントは、次のロケールに対応しています。

| 言語 | ロケールコード |
| --- | --- |
| ブルガリア語 (ブルガリア) | `bg-BG` |
| 中国語 (簡体字) | `zh-Hans` |
| 中国語 (繁体字 - 香港) | `zh-Hant-HK` |
| 中国語 (繁体字 - 台湾) | `zh-Hant-TW` |
| クロアチア語 (クロアチア) | `hr-HR` |
| チェコ語 (チェコ) | `cs-CZ` |
| デンマーク語 (デンマーク) | `da-DK` |
| オランダ語 (オランダ) | `nl-NL` |
| 英語 (オーストラリア) | `en-AU` |
| 英語 (インド) | `en-IN` |
| 英語 (アイルランド) | `en-IE` |
| 英語 (ニュージーランド) | `en-NZ` |
| 英語 (シンガポール) | `en-SG` |
| 英語 (イギリス) | `en-GB` |
| 英語 (アメリカ) | `en-US` |
| エストニア語 (エストニア) | `et-EE` |
| フィリピノ語 (フィリピン) | `fil-PH` |
| フィンランド語 (フィンランド) | `fi-FI` |
| フランス語 (カナダ) | `fr-CA` |
| フランス語 (フランス) | `fr-FR` |
| ドイツ語 (ドイツ) | `de-DE` |
| ギリシャ語 (ギリシャ) | `el-GR` |
| ハンガリー語 (ハンガリー) | `hu-HU` |
| インドネシア語 (インドネシア) | `id-ID` |
| イタリア語 (イタリア) | `it-IT` |
| 日本語 (日本) | `ja-JP` |
| 韓国語 (韓国) | `ko-KR` |
| ラトビア語 (ラトビア) | `lv-LV` |
| リトアニア語 (リトアニア) | `lt-LT` |
| マレー語 (マレーシア) | `ms-MY` |
| マルタ語 (マルタ) | `mt-MT` |
| ノルウェーブークモール語 (ノルウェー) | `nb-NO` |
| ポーランド語 (ポーランド) | `pl-PL` |
| ポルトガル語 (ブラジル) | `pt-BR` |
| ポルトガル語 (ポルトガル) | `pt-PT` |
| ルーマニア語 (ルーマニア) | `ro-RO` |
| スロバキア語 (スロバキア) | `sk-SK` |
| スロベニア語 (スロベニア) | `sl-SI` |
| スペイン語 (アルゼンチン) | `es-AR` |
| スペイン語 (ブラジル) | `es-BR` |
| スペイン語 (中南米) | `es-419` |
| スペイン語 (メキシコ) | `es-MX` |
| スペイン語 (スペイン) | `es-ES` |
| スウェーデン語 (スウェーデン) | `sv-SE` |
| タイ語 (タイ) | `th-TH` |
| トルコ語 (トルコ) | `tr-TR` |
| ベトナム語 (ベトナム) | `vi-VN` |

## Connect の埋め込みコンポーネントでのユーザー認証

通常、Connect の埋め込みコンポーネントはユーザー認証を必要としません。特定のシナリオで Connect の埋め込みコンポーネントは、必要な機能 (例: [アカウント登録](https://docs.stripe.com/connect/supported-embedded-components/account-onboarding.md)コンポーネントを使用したアカウントの法人情報の入力) にアクセスする前に、連結アカウントが Stripe アカウントでサインインする必要があります。その他のコンポーネントの場合、最初にレンダリングされた後でコンポーネント内での認証が必要になることがあります。

要件が変更された場合に Stripe が更新情報を収集する責任を負う場合、認証は必須です。要件が期限切れになったときや変更されたときに最新情報を収集する責任を負う連結アカウント (Custom アカウントなど) の場合、Stripe の認証はアカウントセッション機能 ([disable_stripe_user_authentication](https://docs.stripe.com/api/account_sessions/create.md#create_account_session-components-account_onboarding-features-disable_stripe_user_authentication)) によって制御されます。[ベストプラクティス](https://docs.stripe.com/connect/risk-management/best-practices.md#prevent-account-take-overs)として、2 段階認証または同等のセキュリティ対策を導入することをお勧めします。Custom など、この機能をサポートするアカウント設定では、連結アカウントが[マイナス残高](https://docs.stripe.com/connect/risk-management/best-practices.md#decide-your-approach-to-negative-balance-liability)を返済できない場合、お客様がそのアカウントに対する責任を負うことになります。

### 認証が必要なコンポーネント

連結アカウントには、アプリケーション内で認証済みの [WebView](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession) が表示されます。WebView 内でワークフローを続行する前に、連結アカウントは認証を終える必要があります。

Stripe のオンライン認証フローには、[Connect の設定](https://dashboard.stripe.com/account/applications/settings)で設定されているブランド名、色、アイコンが表示され、認証が完了するまで[埋め込みコンポーネントマネージャー](https://docs.stripe.com/connect/get-started-connect-embedded-components.md#configuring-connect)のカスタムデザインとフォントは適用されません。

以下のコンポーネントは、特定のシナリオでは連結アカウントによる認証が必要になります。

- [アカウント登録](https://docs.stripe.com/connect/supported-embedded-components/account-onboarding.md)
- [入金](https://docs.stripe.com/connect/supported-embedded-components/payouts.md)

## 読み込みエラーを処理する [クライアント側]

コンポーネントの `onLoadError` リスナーメソッドを実装することにより、コンポーネントのロードの失敗に対応します。

さまざまな失敗原因によって `onLoadError` メソッドが複数回呼び出される可能性があります。したがって、`onLoadError` によってトリガーされるロジックはすべてべき等である必要があります。

#### Swift

```swift
// All components emit load errors. This example uses AccountOnboarding.
// All components support didFailLoadWithError.
class MyViewController: UIViewController, AccountOnboardingControllerDelegate {
    func openAccountOnboarding() {
        let accountOnboardingController = embeddedComponentManager.createAccountOnboardingController();
        accountOnboardingController.delegate = self
        accountOnboardingController.present(from: self)
    }

    // MARK: - AccountOnboardingControllerDelegate
    func accountOnboarding(_ accountOnboarding: AccountOnboardingController, didFailLoadWithError error: Error) {
        print("Account onboarding failed to load with error '\(error)'")
    }
}
```
