# 実装方法を設定する

Stripe Terminal SDK またはサーバー主導型の組み込みを設定して、対面決済の受け付けを開始できるようにします。

# iOS


利用可能なすべてのメソッド、オブジェクト、エラーの詳細を確認するには、Stripe の [SDK リファレンス完全版](https://stripe.dev/stripe-terminal-ios)を参照してください。

iOS SDK の使用を開始する際に必要なステップは以下の 4 つです。

1. アプリに [SDK をインストール](https://docs.stripe.com/terminal/payments/setup-integration.md#install)します。
2. アプリを[設定](https://docs.stripe.com/terminal/payments/setup-integration.md#configure)します。
3. アプリとバックエンドで[接続トークンのエンドポイントを設定](https://docs.stripe.com/terminal/payments/setup-integration.md#connection-token)します。
4. アプリで [SDK を初期化](https://docs.stripe.com/terminal/payments/setup-integration.md#initialize)します。

## SDK をインストールする [クライアント側]

Stripe Terminal iOS SDK は、次のようなアプリと互換性があります。

- iOS 15 以上に対応
- CocoaPods、Swift Package Manager を使用するか、手動でフレームワークを導入することによってインストールされている

#### 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 'StripeTerminal', '~> 5.0'
   ```

4. 以下のコマンドを実行します。

   ```bash
   pod install
   ```

5. これ以降は、Xcode でプロジェクトを開く際に、`.xcodeproj` ファイルではなく、`.xcworkspace` ファイルを使用します。

#### Swift Package Manager

1. Xcode で、メニューバーの **File** > **Add Packages…** を選択します
2. Stripe Terminal iOS SDK の GitHub URL を入力します: `https://github.com/stripe/stripe-terminal-ios-spm`
3. プロジェクトにインストールする SDK バージョンを入力します。デフォルト値の「Up to Next Major」を指定すると、互換性に関わる変更の影響を受けることなく、セキュリティと機能を最新の状態に更新できます。

#### 手動

1. GitHub の Stripe Terminal iOS リポジトリーにアクセスして、[最新リリース](https://github.com/stripe/stripe-terminal-ios/releases) に移動します。
2. GitHub リリースに添付されている `StripeTerminal.xcframework.zip` ファイルをダウンロードします。
3. ファイルを解凍してから、XCFramework を Xcode プロジェクトにドラッグアンドドロップします。
4. フレームワークの記号が読み込めない場合は、ターゲットの「General (一般)」ペインに移動し、「Frameworks, Libraries, and Embedded Content (フレームワーク、ライブラリー、埋め込みコンテンツ)」ドロップダウンを探します。`StripeTerminal.xcframework` を、「Don’t Embed (埋め込まない)」から「Embed and Sign (埋め込んで署名)」に切り替えます。

> 最新の SDK リリースと過去のバージョンの詳細については、GitHub の [リリース](https://github.com/stripe/stripe-terminal-ios/releases) ページを参照してください。新しいリリースが公開されたときに通知を受け取るには、[リポジトリのリリースを確認](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-repository) するか、[GitHub リリース RSS フィードを購読](https://github.com/stripe/stripe-terminal-ios/releases.atom) してください。
> 
> 以前のバージョンの iOS SDK からの移行の詳細については、[Stripe Terminal SDK 移行ガイド](https://docs.stripe.com/terminal/references/sdk-migration-guide.md)をご覧ください。

## アプリを設定する [クライアント側]

アプリが Stripe Terminal SDK で動作するように準備するには、Xcode の **Info.plist** ファイルにいくつかの変更を加えます。

1. 次のキーと値のペアを使用して位置サービスを有効にします。

| プライバシー: Location When In Use Usage Description (使用されている位置の確認に関する記述) |
| ------------------------------------------------------------------- |
| **キー**                                                              | [NSLocationWhenInUseUsageDescription](https://developer.apple.com/documentation/bundleresources/information_property_list/nslocationwheninuseusagedescription) |
| **値**                                                               | **決済を受け付けるには、位置情報へのアクセスが必要です。**                                                                                                                                |

   決済に関連する不正使用のリスクを減らし、不審請求の申請を最小限に抑えるため、Stripe は決済が発生した場所を把握する必要があります。SDK が iOS デバイスの場所を特定できない場合は、位置情報へのアクセスが復元されるまで決済無効化されます。

2. アプリがバックグラウンドで実行され、モバイルリーダーに接続されたままであることを確認してください。

| モバイルリーダーに必要なバックグラウンドモード |
| ----------------------- |
| **キー**                  | [UIBackgroundModes](https://developer.apple.com/documentation/bundleresources/information_property_list/uibackgroundmodes) |
| **値**                   | **bluetooth-central** (Bluetooth LE アクセサリーを使用)                                                                             |

   [bluetooth-central](https://developer.apple.com/library/archive/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/CoreBluetoothBackgroundProcessingForIOSApps/PerformingTasksWhileYourAppIsInTheBackground.html#//apple_ref/doc/uid/TP40013257-CH7-SW6) バックグラウンドモードを設定すると、アプリがバックグラウンドで実行されている場合、または iOS デバイスがロックされている場合に、リーダーをスタンバイモードで保持することができます。この値がないと、スタンバイは失敗します。アプリがバックグラウンドで実行されている場合、リーダーは電力を節約するために自動的にオフになります。

3. アプリで Bluetooth に対する権限のダイアログを表示できるようにします。これは、アプリがモバイルリーダーへの接続に対応していない場合でも、App Store の規定により、この設定を含める必要があります。

| プライバシー: Bluetooth Always Usage Description (Bluetooth の常時使用に関する記述) |
| ------------------------------------------------------------------ |
| **キー**                                                             | [NSBluetoothAlwaysUsageDescription](https://developer.apple.com/documentation/bundleresources/information_property_list/NSBluetoothAlwaysUsageDescription) |
| **値**                                                              | **このアプリは、Bluetooth を使用してサポート対象のカードリーダーに接続します。**                                                                                                            |

   iOS 13 では、アプリによる Bluetooth 周辺機器の使用に関して、これまでよりも具体的な権限が新たに導入されました。Core Bluetooth とリンクするアプリは、初回起動時にアプリがクラッシュしないように、このキーを Info.plist ファイルに含める必要があります。

4. App Store に提出する際に、アプリの検証確認を渡します。SDK バージョン 3.4.0 では、この権限要件は削除されています。

| プライバシー: Bluetooth Peripheral Usage Description (Bluetooth 周辺機器の使用に関する記述) |
| ------------------------------------------------------------------------ |
| **キー**                                                                   | [NSBluetoothPeripheralUsageDescription](https://developer.apple.com/documentation/bundleresources/information_property_list/nsbluetoothperipheralusagedescription) |
| **値**                                                                    | **サポート対象のカードリーダーに接続するには、Bluetooth 接続が必要です。**                                                                                                                       |

   これは一例です。アプリ内でのユーザーの権限を求めるプロンプトの文言を変更することもできます。

5. アプリの **Info.plist** を保存します。これで、正しく設定され、Stripe Terminal SDK で使用できるようになりました。

> iPhone のタッチ決済を使用している場合は、Apple 開発者アカウントから iPhone のタッチ決済開発エンタイトルメントを [リクエストおよび設定](https://developer.apple.com/documentation/proximityreader/setting-up-the-entitlement-for-tap-to-pay-on-iphone) する必要があります。

## ConnectionToken エンドポイントを設定する [サーバー側] [クライアント側]

### サーバー側

リーダーに接続するには、バックエンドからご自身の Stripe アカウントに、リーダーを使用するための SDK 権限を付与する必要があります。それには、[ConnectionToken (接続トークン)](https://docs.stripe.com/api/terminal/connection_tokens.md) から [secret (シークレット)](https://docs.stripe.com/api/terminal/connection_tokens/object.md#terminal_connection_token_object-secret) を提供します。バックエンドは信頼できるクライアントに対してのみ、接続トークンを作成するようにする必要があります。

#### curl

```bash
curl https://api.stripe.com/v1/terminal/connection_tokens \
  -u <<YOUR_SECRET_KEY>>: \
  -X "POST"
```

サーバー側の `ConnectionToken` からシークレットを取得してクライアント側に渡します。

#### Ruby

```ruby
post '/connection_token' do
  token = # ... Create or retrieve the ConnectionToken
  {secret: token.secret}.to_json
end
```

> `ConnectionToken` の `secret` により、お客様は任意の Stripe Terminal リーダーに接続して、Stripe アカウントで支払いを受け取ることができます。必ず、接続トークンの作成に使用するエンドポイントを認証し、クロスサイトリクエストフォージェリ (CSRF) から保護してください。

### クライアント側

SDK にこのエンドポイントへのアクセスを許可するには、アプリに [ConnectionTokenProvider](https://stripe.dev/stripe-terminal-ios/docs/Protocols/SCPConnectionTokenProvider.html) プロトコルを実装します。これは、バックエンドから `ConnectionToken` を要求する単一の関数を定義します。

```swift
import StripeTerminal

// Example API client class for communicating with your backend
class APIClient: ConnectionTokenProvider {

    // For simplicity, this example class is a singleton
    static let shared = APIClient()

    // Fetches a ConnectionToken from your backend
    func fetchConnectionToken(_ completion: @escaping ConnectionTokenCompletionBlock) {
        let config = URLSessionConfiguration.default
        let session = URLSession(configuration: config)
        guard let url = URL(string: "https://{{YOUR_BACKEND_URL}}/connection_token") else {
            fatalError("Invalid backend URL")
        }
        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        let task = session.dataTask(with: request) { (data, response, error) in
            if let data = data {
                do {
                    // Warning: casting using `as? [String: String]` looks simpler, but isn't safe:
                    let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]
                    if let secret = json?["secret"] as? String {
                        completion(secret, nil)
                    }
                    else {
                        let error = NSError(domain: "com.stripe-terminal-ios.example",
                                            code: 2000,
                                            userInfo: [NSLocalizedDescriptionKey: "Missing `secret` in ConnectionToken JSON response"])
                        completion(nil, error)
                    }
                }
                catch {
                    completion(nil, error)
                }
            }
            else {
                let error = NSError(domain: "com.stripe-terminal-ios.example",
                                    code: 1000,
                                    userInfo: [NSLocalizedDescriptionKey: "No data in response from ConnectionToken endpoint"])
                completion(nil, error)
            }
        }
        task.resume()
    }
}
```

この関数は、SDK で Stripe またはリーダーの認証が必要になるたびに呼び出されます。また、リーダーへの接続に新しい接続トークンが必要な場合 (アプリがリーダーから切断されたときなど) にも呼び出されます。SDK がバックエンドから新しい接続トークンを取得できない場合、リーダーへの接続は失敗し、サーバーからエラーが返されます。

> 接続トークンのキャッシュやハードコードはしないでください。SDK が接続トークンのライフサイクルを管理します。

ネットワークセキュリティには留意すべき考慮事項もいくつかあります。

> #### 証明書のピンニング
> 
> ほとんどの場合、アプリケーションで証明書のピンニングを設定する必要はありません。アプリケーションにこの機能が必要な場合は、[証明書のピンニング](https://docs.stripe.com/tls-certificates.md#certificate-pinning)に関するドキュメントをご覧ください。

## SDK を初期化する [クライアント側]

Stripe Terminal SDK によって提供される [Terminal](https://stripe.dev/stripe-terminal-ios/docs/Classes/SCPTerminal.html) クラスは、リーダーの検出、リーダーへの接続、リーダーでの操作の実行 (カートの詳細の表示、支払いの作成、将来の使用に備えたカードの保存など) のための汎用インターフェイスを表示します。

[接続トークンの設定](https://docs.stripe.com/terminal/payments/setup-integration.md#connection-token)時に実装した `ConnectionTokenProvider` を指定します。`Terminal.shared` にアクセスする前に、アプリで `initWithTokenProvider` を 1 回だけ呼び出します。通常は、`AppDelegate` メソッドの `application:didFinishLaunchingWithOptions` または SwiftUI `App` タイプの `init()` で呼び出します。あるいは、Objective-C で `dispatch_once` を使用するか、Swift で `static` イニシャライザを使用します。

```swift
import UIKit
import StripeTerminal

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        Terminal.initWithTokenProvider(APIClient.shared)
        // ...
        return true
    }

    // ...

}
```

## SDK の更新

Stripe は定期的に、新機能、バグ修正、セキュリティー更新を含む更新をリリースしています。SDK は、新しいバージョンが利用可能になり次第すぐに更新してください。現在利用可能な SDK は以下のとおりです。

- [Stripe Terminal Android SDK](https://github.com/stripe/stripe-terminal-android/releases)
- [Stripe Terminal iOS SDK](https://github.com/stripe/stripe-terminal-ios/releases)
- [Stripe Terminal JavaScript SDK](https://docs.stripe.com/terminal/references/api/js-sdk.md#changelog)
- [Stripe Terminal React Native SDK](https://github.com/stripe/stripe-terminal-react-native)

## 次のステップ

- [リーダーに接続する](https://docs.stripe.com/terminal/payments/connect-reader.md?terminal-sdk-platform=ios&reader-type=internet)

