> For the complete documentation index, see [llms.txt](https://docs.payments.thalescloud.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.payments.thalescloud.io/nfc-wallet-sdk-ios/ja/implement-nfc-wallet/make-payments/implement-contactless-payment/4.-implement-payment.md).

# 4. 支払いを実装する

これで、各非接触決済のエクスペリエンスを実装できます:

* **ダブルクリック**: デフォルトの支払いカードを使用して非接触決済を開始します。
* **フィールド検知**: POSリーダーが検知されたときに非接触決済を開始します。
* **手動モード**: エンドユーザーがカードを選択した後に非接触決済を開始します。

次の場合 **フィールド検出**、続行するようエンドユーザーに促す必要がある場合があります。次のいずれかを使用します **ダブルクリック** または **手動モード**.

次の場合 **手動モード**、エンドユーザーがカードを選択できるUIを追加します。その後、そのカードで支払いを開始します。

### 支払いを開始 <a href="#start-payment" id="start-payment"></a>

次を呼び出して非接触決済を開始します `startPayment(withDigitalCardID:)`.

{% hint style="info" %}
`digitalCardID` は省略可能です。

* 指定すると `digitalCardID` 特定のカードで支払えます。\nこれは次の場合に使用します **手動モード**.
* 省略すると `digitalCardID` SDK がデフォルトの支払いカードを使用します。\nこれは次の場合に使用します **ダブルクリック**.

デフォルトの支払いカードがどのように選択されるかについては、次を参照してください [デフォルトの支払いカードを設定](/nfc-wallet-sdk-ios/ja/implement-nfc-wallet/manage-digital-cards/set-default-payment-card.md).
{% endhint %}

```swift
// 提供された digitalCardID を使用して支払いを開始
// ユースケース: 手動モード（ユーザー操作あり）
await session.startPayment(withDigitalCardID: digitalCardID)

// デフォルトカードで支払いを開始
// ユースケース: ダブルクリック
await session.startPayment()
```

この呼び出しで支払いセッションが開始されます。

その後、あなたのイシュアアプリケーションは次のことを行う必要があります:

1. 次を監視します `ContactlessPaymentSession.eventStream`.
2. 各イベントを処理します。

{% hint style="info" %}
デジタルウォレットアプリケーションでもトランザクションデータを添付できます。次を参照してください [ウォレットのトランザクションデータを設定](/nfc-wallet-sdk-ios/ja/additional-features/add-wallet-transaction-data.md).
{% endhint %}

### 非接触決済イベントを処理

次を呼び出した後に `startPayment(...)`、次を反復処理します `ContactlessPaymentSession.eventStream`。各項目は次のいずれかです `ContactlessPaymentSession.Event`.

フローが次で終了するまでイベントを処理します `.transactionCompleted` または `.errorEncountered`.

* `.authenticationRequired(let authentication)`: エンドユーザーの認証を要求します（たとえば、Touch ID や Face ID）。
  * 次を呼び出します `authentication.proceed()` で認証を求め、フローを継続します。
  * 次を呼び出します `authentication.cancel()` でフローを停止します。その後、次を受け取ります `.errorEncountered` で `キャンセルされました`.
* `.authenticationCompleted`: 認証が成功したことを確認します。通常は次にカードエミュレーションを開始します。
* `.posConnected`: デバイスがPOS端末のRFフィールド内にあることを示します。\niOS 18 では、このイベントを受信するには presentment intent assertion を使用する必要があります。
* `.posDisconnected`: トランザクションがまだ進行中の間に、デバイスがPOS端末のフィールドから離れたことを示します。
* `.transactionCompleted(let transactionContext)`: トランザクションが正常に完了したことを示します。次を使用して `transactionContext` ステータスやレシートを表示します。
* `.errorEncountered(let error)`: エラーによりフローが終了したことを示します。次を参照してください [エラーを処理](#example-of-a-full-implementation)

```swift
func startContactlessPayment() async {
  let contactlessPaymentSession = ContactlessPaymentSession()
  contactlessPaymentSession.startPayment()
        
  for await state in contactlessPaymentSession.eventStream {
    switch state {
      case .authenticationRequired(let authentication):
        // 認証を続行します。生体認証が求められます
        authentication.proceed()
        //authentication.cancel()
      case .authenticationCompleted:
        // 認証は成功しました。
        contactlessPaymentSession.startEmulation()
      case .posConnected: break
        // 情報: アプリケーションを更新し、エンドユーザーに情報を表示します
      case .posDisconnected: break
        // 情報: アプリケーションを更新し、エンドユーザーに情報を表示します
      case .transactionCompleted(let transactionContext): break
        // エンドユーザーに UI を表示します
      case .errorEncountered(let error): break
        // エンドユーザーに UI を表示します
    }
  }
}
```

### エミュレーションを開始

次を呼び出します `startEmulation()` 次を受け取った後に `ContactlessPaymentSession.Event.authenticationCompleted`.

これによりカードエミュレーションが開始され、エンドユーザーに NFC モーダル UI が表示されます:

<div align="left"><figure><img src="https://3629066568-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F6bUtiXdSFHu8lmOj8A0X%2Fuploads%2FA51COx0KFdjuaZR6FQW9%2Fimage.png?alt=media&amp;token=54b6ea4d-b6e1-41f9-832e-a0c9eac6f8d0" alt=""><figcaption><p>認証後に表示される NFC モーダルユーザーインターフェイス。</p></figcaption></figure></div>

NFC モーダル UI が表示されている間、SDK は field-detect イベントを抑制します。

SDK は POS 端末との APDU (Application Protocol Data Unit) 交換も有効にします。

エンドユーザーは 60 秒以内に非接触決済を完了する必要があります。

時間切れになると、SDK は次を発行します `.errorEncountered` で `maxSessionDurationReached`.

次を呼び出すことができます `startEmulation()` 複数回。

```swift
contactlessPaymentSession.startEmulation()
```

### 支払いカードを変更する

使用する `startPayment(withDigitalCardID:)` エンドユーザーがデフォルト以外の支払いカードで支払いたい場合に使用します。

この API は:

* 選択したカードをデフォルトの支払いカードとして設定します（更新が成功した場合）。
* そのカードで支払いフローを続行します。

{% hint style="warning" %}
この呼び出しはデフォルトの支払いカードを変更します **永続的に**。\nSDK がデフォルトの支払いカードの更新に成功した場合、支払いが失敗またはキャンセルされても、そのカードは選択されたままになります。
{% endhint %}

次を呼び出すタイミングに応じて、以下のいずれかのフローを選択します `startEmulation()`.

#### シナリオ A: 認証後にエミュレーションを開始

次を呼び出します `startEmulation()` 次を受け取ったときに `ContactlessPaymentSession.Event.authenticationCompleted`.

* 認証後すぐに NFC モーダル UI が表示されます。
* カードを変更するには、エンドユーザーは次を行う必要があります:
  1. タップする **キャンセル** を NFC モーダル UI で。
  2. UI で別のカードを選択します。
  3. 次を呼び出します `startPayment(withDigitalCardID:)` 新しい次を使って再度 `digitalCardID`.

#### シナリオ B: POS 端末のタップでエミュレーションを開始

次を呼び出します `startEmulation()` 次を受け取ったときに `ContactlessPaymentSession.Event.posConnected`.

* エンドユーザーは POS 端末をタップする前に、UI でカードを切り替えることができます。
* デバイスが RF フィールドに入った後にのみ NFC モーダル UI が表示されます。

{% hint style="info" %}
シナリオ B では次が必要です `NFCPresentmentIntentAssertion` リーダー検知を制御し、システムがデフォルトの支払いアプリケーションを起動しないようにすることです。

* イシュアアプリケーションが **ない** デフォルトの支払いアプリケーション（iOS 17.4 および iOS 18）である場合は、次を使用する必要があります `NFCPresentmentIntentAssertion`。そうしないと、デフォルトの支払いアプリケーションが起動し、支払いフローを進めることができません。
* イシュアアプリケーションが **が** デフォルトの支払いアプリケーション（iOS 18）である場合は、次を使用する必要があります `NFCPresentmentIntentAssertion` を受け取るために `ContactlessPaymentSession.Event.posConnected` リーダー検知から。これがないと、リーダー検知は次を通じて配信されます `NFCWindowSceneEvent.readerDetected` あなたの `SceneDelegate`.
  {% endhint %}

### 非接触決済をキャンセル <a href="#cancel-contactless-payment" id="cancel-contactless-payment"></a>

進行中の非接触決済を次を呼び出してキャンセルします `cancel()`.

その後、あなたのイシュアアプリケーションは次を受け取ります `.errorEncountered` で `キャンセルされました`。これを使って UI 状態をリセットします。

```swift
contactlessPaymentSession.cancel()
```

### アラートメッセージを設定 <a href="#set-alert-message" id="set-alert-message"></a>

NFC モーダル UI に表示されるメッセージを設定します。

```swift
contactlessPaymentSession.setAlertMessage("POS Connected")
```

### エラーを処理する <a href="#example-of-a-full-implementation" id="example-of-a-full-implementation"></a>

フローが次で終了した場合 `ContactlessPaymentSession.Event.errorEncountered(let error)`、支払いは失敗と見なします。以下の表は、考えられるエラーの一覧をまとめたものです:

| エラー                                | 説明                                                                                                     |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `キャンセルされました`                       | ユーザーがトランザクションをキャンセルしました。                                                                               |
| `maxSessionDurationReached`        | 最大継続時間に達したため、セッションの有効期限が切れました。                                                                         |
| `nfcPermissionNotAccepted`         | NFC 接続の権限が付与されていません。                                                                                   |
| `systemEligibilityFailed`          | システムは非接触決済の対象ではありません。例: Apple ID またはデバイスの所在地が EEA にありません。                                              |
| `keychainError`                    | キーチェーン操作でエラーが発生しました。                                                                                   |
| `noDefaultCard`                    | トランザクション前にデフォルトカードが設定されていません。                                                                          |
| `noPaymentKeys`                    | そのカードの支払いキーがありません。補充を要求する必要があります。                                                                      |
| `apduFailure`                      | デバイスと POS 端末間の APDU 交換でエラーが発生しました。                                                                     |
| `transmissionError`                | 一般的な送信エラーです。NFC リーダーとの接続がまだ有効であれば、送信操作を再試行できます。                                                        |
| `sessionInvalidated`               | カードセッションはシステムによって無効化されました。例: アプリケーションがバックグラウンドにあります。                                                   |
| `unknown`                          | トランザクション中に不明なエラーが発生しました。                                                                               |
| `deviceEnvironmentUnsafe`          | デバイス環境が安全でないエラー。                                                                                       |
| `setDefaultCardFailure`            | 次のときに、指定されたデジタルカード ID をデフォルトカードとして設定しようとするとエラーが発生します `startPayment(withDigitalCardID:)` API が呼び出された場合。 |
| `invalidDigitalCardID`             | 次のときに、指定された Digital Card ID が無効である場合にエラーが発生します `startPayment(withDigitalCardID:)`.                     |
| `authenticationExpired` が呼び出された場合。 | 認証の有効期限後に支払いが行われるとエラーが発生します。                                                                           |
| `posNotSupported`                  | POS 端末のリストに選択した AID がない場合にエラーが発生します。                                                                   |
| `cardNotSupported`                 | そのカードは非接触決済に対応していません。                                                                                  |
| `cardNotActive`                    | そのカードは有効ではありません。                                                                                       |
| `authenticationKeyInvalidated`     | デバイスのパスコードがオフになり、保護されたデータが消去されるとエラーが発生します。パスコードを再度有効にして、設定を再初期化してください。                                 |
| `biometricNotEnrolled`             | 生体認証データが登録されていない、またはサポートされていない場合にエラーが発生します。                                                            |
| `authenticationFailed`             | 認証がキャンセルされた場合、アプリが中断された場合、またはデバイスのパスコードがない場合にエラーが発生します。                                                |

{% hint style="warning" %}
NFC Wallet SDK は、 `authenticationKeyInvalidated` が発生すると、保存された認証情報を自動的に消去します（たとえば、パスコードのリセットやセキュリティ変更後）。

アプリケーションでは、エンドユーザーに再登録の手順を案内する必要があります。
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.payments.thalescloud.io/nfc-wallet-sdk-ios/ja/implement-nfc-wallet/make-payments/implement-contactless-payment/4.-implement-payment.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
