# 実装方法を設定する

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

# React Native


> Terminal の React Native ライブラリは[公開プレビュー](https://docs.stripe.com/release-phases.md)中で、現在開発中です。問題が発生した場合は、[GitHub プロジェクト](https://github.com/stripe/stripe-terminal-react-native/issues/new/choose) に報告してください。

React Native 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)します。

> **Apps on Devices** 導入を構築している場合 (S700/S710 などの Stripe スマートリーダーでアプリを実行) は、このガイドに従ってから、追加の [Android ネイティブ設定ステップ](https://docs.stripe.com/terminal/features/apps-on-devices/build.md?terminal-sdk-platform=react-native#setup-app) を実行する必要もあります。

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

[React Native SDK](https://github.com/stripe/stripe-terminal-react-native) はオープンソースであり、詳細なドキュメントが提供されています。この内部ではネイティブの iOS SDK および Android SDK が使用されます。以下を実行して SDK をインストールします。

#### NPM

```bash
npm install @stripe/stripe-terminal-react-native
```

#### Yarn

```bash
yarn add @stripe/stripe-terminal-react-native
```

#### Expo

```bash
npx expo install @stripe/stripe-terminal-react-native
```

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

#### React Native CLI

#### iOS

### Pod

ネイティブ依存関係をインストールするには、`ios` ディレクトリーで `pod install` を実行する必要があります。

### 権限

アプリが 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) する必要があります。

#### Android

### 権限

Stripe Terminal SDK を正しく機能させるには、次の Android 権限が必要です。

- `PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT`
- `PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN`
- `PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION`

Terminal SDK を初期化する前に、`requestNeededAndroidPermissions` ヘルパー関数を使用して、必要なすべての権限を自動的にリクエストしてください。

```js
import { requestNeededAndroidPermissions } from '@stripe/stripe-terminal-react-native';

try {
  const granted = await requestNeededAndroidPermissions({
    accessFineLocation: {
      title: 'Location Permission',
      message: 'Stripe Terminal needs access to your location',
      buttonPositive: 'Accept',
    },
  });
  if (granted) {
    // Initialize the SDK
  } else {
    console.error(
      'Location and BT services are required to connect to a reader.'
    );
  }
} catch (e) {
  console.error(e);
}
```

また、権限リクエストを細かく制御する必要がある場合は、`PermissionsAndroid.request` を使用して各権限を手動でリクエストできます。

```js
import { PermissionsAndroid } from 'react-native';

// Mobile readers using Bluetooth connection require BLUETOOTH_CONNECT, BLUETOOTH_SCAN, and ACCESS_FINE_LOCATION.
// This example shows the pattern for requesting one permission.
const granted = await PermissionsAndroid.request(
  PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
  {
    title: 'Location Permission',
    message: 'Stripe Terminal needs access to your location',
    buttonPositive: 'Accept',
  },
);

if (granted === PermissionsAndroid.RESULTS.GRANTED) {
  console.log('Location permission granted');
} else {
  console.error('Location permission denied');
}
```

### マニフェスト

Android 12 以降との互換性を確保するため、必ず `android:exported="true"` を `AndroidManifest.xml` に追加してください。

```xml
<manifest ...>
    <application android:name=".MainApplication">
      <activity
        android:name=".MainActivity"
        android:exported="true">
          <!-- content -->
      </activity>
    </application>
</manifest>
```

Android 12 で行われた変更についての詳細は、[Android のドキュメント、コンポーネントのエクスポートの安全性を改善](https://developer.android.com/about/versions/12/behavior-changes-12#exported)をご覧ください。

Android 11 以前を実行するデバイスについては、マニフェストでも権限を付与する必要があります。

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.stripeterminalreactnative">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
</manifest>
```

#### Expo

> [カスタムネイティブコード](https://docs.expo.io/workflow/customizing/)が必要なため、このパッケージは「Expo Go」アプリでは使用できません。ネイティブプロジェクトを生成し、`npx expo run:ios` または `npx expo run:android` を使用してアプリを実行するには、`npx expo prebuild` を使用する必要があります。

#### iOS

### SDK を設定する

SDK を[インストール](https://docs.stripe.com/terminal/payments/setup-integration.md#install)した後、[設定プラグイン](https://docs.expo.io/guides/config-plugins/)を `app.json` または `app.config.js` の [plugins](https://docs.expo.io/versions/latest/config/app/#plugins) 配列に追加します。

お使いのリーダーの種類に応じて、以下の設定オプションを設定してください。

- `localNetworkUsagePermission` - LAN 接続を使用するスマートリーダーに必須です
- `appDelegate` - Android のタッチ決済に必須です
- `tapToPayCheck` - タッチ決済互換性チェックを有効にします

```json
{
  "expo": {
    "plugins": [
      [
        "@stripe/stripe-terminal-react-native",
        {
          "bluetoothBackgroundMode": true,
          "locationWhenInUsePermission": "Location access is required to accept payments.",
          "bluetoothPeripheralPermission": "Bluetooth access is required to connect to supported bluetooth card readers.",
          "bluetoothAlwaysUsagePermission": "This app uses Bluetooth to connect to supported card readers.",
          "localNetworkUsagePermission": "This app uses the local WiFi network to connect to supported card readers.",
          "appDelegate": true,
          "tapToPayCheck": true
        }
      ]
    ]
  }
}
```

### 構築する

次に、以下を使用し、[カスタムのネイティブコードを追加する](https://docs.expo.io/workflow/customizing/)ガイドの説明に従って、アプリを再構築します。

```bash
npx expo prebuild
```

次に、以下を実行します。

```bash
npx expo run:ios
```

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

#### Android

### 権限

Stripe Terminal SDK を正しく機能させるには、次の Android 権限が必要です。

- `PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT`
- `PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN`
- `PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION`

Terminal SDK を初期化する前に、`requestNeededAndroidPermissions` ヘルパー関数を使用して、必要なすべての権限を自動的にリクエストしてください。

```js
import { requestNeededAndroidPermissions } from '@stripe/stripe-terminal-react-native';

try {
  const granted = await requestNeededAndroidPermissions({
    accessFineLocation: {
      title: 'Location Permission',
      message: 'Stripe Terminal needs access to your location',
      buttonPositive: 'Accept',
    },
  });
  if (granted) {
    // Initialize the SDK
  } else {
    console.error(
      'Location and BT services are required to connect to a reader.'
    );
  }
} catch (e) {
  console.error(e);
}
```

また、権限リクエストを細かく制御する必要がある場合は、`PermissionsAndroid.request` を使用して各権限を手動でリクエストできます。

```js
import { PermissionsAndroid } from 'react-native';

// Mobile readers using Bluetooth connection require BLUETOOTH_CONNECT, BLUETOOTH_SCAN, and ACCESS_FINE_LOCATION.
// This example shows the pattern for requesting one permission.
const granted = await PermissionsAndroid.request(
  PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
  {
    title: 'Location Permission',
    message: 'Stripe Terminal needs access to your location',
    buttonPositive: 'Accept',
  },
);

if (granted === PermissionsAndroid.RESULTS.GRANTED) {
  console.log('Location permission granted');
} else {
  console.error('Location permission denied');
}
```

### SDK を設定する

SDK を[インストール](https://docs.stripe.com/terminal/payments/setup-integration.md#install)した後、[設定プラグイン](https://docs.expo.io/guides/config-plugins/)を `app.json` または `app.config.js` の [plugins](https://docs.expo.io/versions/latest/config/app/#plugins) 配列に追加します。

お使いのリーダーの種類に応じて、以下の設定オプションを設定してください。

- `localNetworkUsagePermission` - LAN 接続を使用するスマートリーダーに必須です
- `appDelegate` - Android のタッチ決済に必須です
- `tapToPayCheck` - タッチ決済互換性チェックを有効にします

```json
{
  "expo": {
    "plugins": [
      [
        "@stripe/stripe-terminal-react-native",
        {
          "bluetoothBackgroundMode": true,
          "locationWhenInUsePermission": "Location access is required to accept payments.",
          "bluetoothPeripheralPermission": "Bluetooth access is required to connect to supported bluetooth card readers.",
          "bluetoothAlwaysUsagePermission": "This app uses Bluetooth to connect to supported card readers.",
          "localNetworkUsagePermission": "This app uses the local WiFi network to connect to supported card readers.",
          "appDelegate": true,
          "tapToPayCheck": true
        }
      ]
    ]
  }
}
```

#### 構築する

次に、以下を使用し、[カスタムのネイティブコードを追加する](https://docs.expo.io/workflow/customizing/)ガイドの説明に従って、アプリを再構築します。

```bash
npx expo prebuild
```

次に、以下を実行します。

```bash
npx expo run:android
```

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

### サーバー側

リーダーに接続するには、バックエンドからご自身の 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 にこのエンドポイントへのアクセスを許可するには、バックエンドから `ConnectionToken` をリクエストするトークンプロバイダーの単一の関数を作成します。

```js
import { StripeTerminalProvider } from '@stripe/stripe-terminal-react-native';

const fetchTokenProvider = async () => {
  const response = await fetch(`{YOUR BACKEND URL}/connection_token`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
  });
  const { secret } = await response.json();
  return secret;
};
```

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

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

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

作業を開始するには、[ステップ 3](https://docs.stripe.com/terminal/payments/setup-integration.md#connection-token) で実装したトークンプロバイダーをプロパティとして `StripeTerminalProvider` に渡します。

```js
import { StripeTerminalProvider } from '@stripe/stripe-terminal-react-native';

function Root() {
  const fetchTokenProvider = async () => {
    const response = await fetch(`${API_URL}/connection_token`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
    });
    const { secret } = await response.json();
    return secret;
  };

  return (
    <StripeTerminalProvider
      logLevel="verbose"
      tokenProvider={fetchTokenProvider}
    >
      <App />
    </StripeTerminalProvider>
  );
}
```

最後のステップとして、`useStripeTerminal` フックから `initialize` メソッドを呼び出します。

> `initialize` メソッドは、`StripeTerminalProvider` を含むコンポーネントからではなく、`StripeTerminalProvider` 内にネストされたコンポーネントから呼び出す必要があります。
> 
> 初期化が完了すると、`discoverReaders`、`connectReader`、`processPaymentIntent` などの他の SDK メソッドを使用できます。初期化の前にこれらのメソッドを呼び出そうとすると、「アクションを実行する前に、まず Stripe Terminal SDK を初期化してください」というエラーが表示されます。

```js
function App() {
  const { initialize } = useStripeTerminal();

  useEffect(() => {
    initialize();
  }, []);

  return <View />;
}
```

## 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=react-native&reader-type=internet)

