> 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/additional-features/customize-ppse.md).

# PPSE をカスタマイズ

## 概要

EMV Book Bで定義されているように、PPSE（Proximity Payment System Environment）は非接触決済の入口です。各デジタルカードには、トークンプロファイルで定義される独自のPPSEがあります。そこには、対応するアプリケーションラベルと優先順位を伴う、サポートされるアプリケーション識別子（AID）の一覧が含まれます。

NFC Wallet SDKは次を提供します **PPSE管理API。** これにより、デジタルウォレットアプリケーションは次のことが可能になります。

* 取得する **PPSE** （デジタルカードプロファイルで定義されたデフォルトのPPSE）。
* 取得する **補助PPSE** （co-badgedカード向けの補助デジタルカードプロファイルで定義されたPPSE）。
* 新しいPPSEをカスタマイズする（**カスタムPPSE**).
* 取得またはリセットする **カスタムPPSE**.

NFC Wallet SDKは次を使用します **カスタムPPSE** 非接触トランザクション用に定義されている場合。

{% hint style="info" %}
使用する **PPSE Management API** co-badgedデジタルウォレットプログラムでポリシーを適用するために。

**NFC Wallet SDK** 次のみを使用します **PPSE** または **カスタムPPSE**。次は使用しません **補助PPSE**.
{% endhint %}

## SDK 統合

この **PPSE Management API** には次が含まれます `PPSEFCITemplate` クラスと次の `DigitalCard` 操作：

* `DigitalCard.ppse`：トークンプロファイルで定義されたデフォルトのPPSEを取得します。
* `DigitalCard.auxiliaryPPSE`：補助デジタルカードプロファイルで定義されたPPSE（co-badgedカード）を取得します。
* `DigitalCard.customPPSE`：カスタムPPSEを取得します。返します `nil` 。定義されていない場合は
* `DigitalCard.setCustomPPSE`：カスタムPPSEを設定します。 `nil` を渡すとクリアします。

{% hint style="warning" %}
SDKは、次を呼び出すとPPSEテンプレートを自動的に検証します `DigitalCard.setCustomPPSE`.

参照 [検証ルール](#validation-rules).
{% endhint %}

### カスタムPPSEの作成

カスタムPPSEを次のいずれかの方法で作成します `PPSEFCITemplate` 次のいずれかの方法で：

* 既存のPPSEテンプレートを使用する。
* 生のPPSEバイトを使用する。
* 一から作成する。

#### 方法1：既存のテンプレートからPPSEを作成する

デジタルカードのPPSEを基にして、的を絞った変更を加えたい場合はこの方法を使用します。

**使用する場面：**

* 優先順位やタグなど、既存のPPSEの特定のフィールドをカスタマイズしたい。
* 選択的な変更を加えつつ、デフォルトのPPSE構造を保持したい。
* カスタマイズ用のベーステンプレートが必要。

```swift
var fci = try await card.ppse

let visaAID = Data([0xA0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10])
let visaKernel = Data([0x03])

guard let index = fci.proprietaryTemplate.issuerDiscretionaryData.directoryEntryList.firstIndex(where: { 
    $0.applicationIdentifier == visaAID && $0.kernelIdentifier == visaKernel 
}) else {    
    return
}

let customDiscretionaryData = Data([0xDF, 0x01, 0x02, 0x11, 0x22])

// ディレクトリエントリの下に追加タグを設定
try fci.proprietaryTemplate.issuerDiscretionaryData.directoryEntryList[index].setAdditionalTag(
    value: customDiscretionaryData, 
    forKey: Data([0x73])
)
    
let transitNetworkIdentifier = Data([0x00, 0x00, 0x1A, 0x9F])
fci.proprietaryTemplate.issuerDiscretionaryData.directoryEntryList[index].asrpd = transitNetworkIdentifier

try await card.setCustomPPSE(fci)
```

#### 方法2：生のバイトからPPSEを作成する

完全なPPSE応答データがすでにBER-TLV形式で利用可能な場合はこの方法を使用します。

**使用する場面：**

* 完全なPPSE応答データが生のバイトとしてすでにあります。

```swift
private let knownPPSEFCIHex =
    Data([
        0x6F, 0x6E, 0x84, 0x0E, 0x32, 0x50, 0x41, 0x59, 0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46,
        0x30, 0x31, 0xA5, 0x5C, 0xBF, 0x0C, 0x59, 0x61, 0x2B, 0x4F, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x98,
        0x08, 0x40, 0x50, 0x0B, 0x56, 0x69, 0x73, 0x61, 0x20, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74, 0x87,
        0x01, 0x01, 0xBF, 0x63, 0x04, 0xDF, 0x20, 0x01, 0x00, 0x9F, 0x0A, 0x04, 0x00, 0x01, 0x01, 0x02,
        0x9F, 0x2A, 0x01, 0x03, 0x61, 0x2A, 0x4F, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 0x50,
        0x0A, 0x56, 0x69, 0x73, 0x61, 0x20, 0x44, 0x65, 0x62, 0x69, 0x74, 0x87, 0x01, 0x02, 0xBF, 0x63,
        0x04, 0xDF, 0x20, 0x01, 0x00, 0x9F, 0x0A, 0x04, 0x00, 0x01, 0x01, 0x01, 0x9F, 0x2A, 0x01, 0x03
    ])

let template = try DigitalCard.PPSEFCITemplate(data: knownPPSEFCIHex)

try await card.setCustomPPSE(template)
```

#### 方法3：ゼロからPPSEを作成する

各コンポーネントを個別に定義して、プログラムでPPSE構造を組み立てる必要がある場合はこの方法を使用します。

**使用する場面：**

* 既存のバイトデータなしでPPSEデータを作成しています。
* ディレクトリエントリ、AID、ラベル、その他のPPSEコンポーネントをプログラムで定義する必要があります。
* コンパイル時の検証を伴う型安全な構築を行いたい。
* 生のバイトより構造化オブジェクトを優先したい。

`DigitalCard` PPSE応答を次として公開します `PPSEFCITemplate`。独自のものも作成できます `PPSEFCITemplate`。次の例で方法を示します。

```swift
let dfName = Data([
    0x32, 0x50, 0x41, 0x59, 0x2E, 0x53, 0x59, 0x53, 0x2E, 0x44, 0x44, 0x46, 0x30, 0x31
])

let entry = try DigitalCard.DirectoryEntry(
    applicationIdentifier: Data([0xA0, 0x00, 0x00, 0x00, 0x98, 0x08, 0x40]),
    label: Data([0x56, 0x69, 0x73, 0x61, 0x20, 0x43, 0x72, 0x65, 0x64, 0x69, 0x74]),
    kernelIdentifier: Data([0x03]),
    asrpd: Data([0x00, 0x01, 0x01, 0x02]),
    priority: Data([0x01]),
    additionalTags: [Data([0xBF, 0x63]): Data([0xDF, 0x20, 0x01, 0x00])],
    lockStatus: .unlocked
)

let idd = try DigitalCard.FCIIssuerDiscretionaryData(
    directoryEntryList: entries,
    additionalTags: bf0cAdditionalTags
)

let prop = try DigitalCard.FCIProprietaryTemplate(issuerDiscretionaryData: idd)

let template = try DigitalCard.PPSEFCITemplate(dfName: dfName, proprietaryTemplate: prop)

try await card.setCustomPPSE(template)
```

### カスタムPPSEをクリアする

次を渡して `nil` カスタムPPSEを削除し、デフォルトのPPSE応答を復元します。

```swift
/// 1. 現在のカスタムPPSEを取得（存在する場合）
if let currentPPSE = try? await card.customPPSE {
    print("\\(currentPPSE) PPSEはアクティブです。")
}

// 2. 現在のPPSEを完全に削除する（工場出荷時設定のPPSEに戻す）
try await card.setCustomPPSE(nil)
```

### 検証ルール

NFC Wallet SDKは、次を呼び出すとカスタムPPSEを検証します `DigitalCard.setCustomPPSE`。カスタムPPSEがEMV要件とBER-TLVエンコードに従っていることを保証します。

#### サイズ制限

* シリアル化されたBER-TLVペイロードは256バイト以下でなければなりません。
* 内のカスタムタグキー `BF0C` または `61` は2バイトを超えてはなりません。

#### 必須タグ

あなたの `PPSEFCITemplate` には次を含める必要があります：

1. DF名 — タグ `84`
2. 少なくとも1つのディレクトリエントリ — タグ `61` 内の `BF0C`
3. 各ディレクトリエントリ内のアプリケーション識別子 — タグ `4F`

検証に失敗すると、SDKは次をスローします `DigitialCard.Error.invaldPPSE(_:)` error

#### AIDロックの制限

を使用してAIDをロックすることは `LockStatus.locked` 単一ブランドのVisaカードでのみサポートされています。

を設定した場合 `LockStatus.locked` 未サポートのカードに対して、SDKは次をスローします `DigitialCard.Error.clientError(_:)` error


---

# 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/additional-features/customize-ppse.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.
