> 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/secure-card-display/ja/implement-secure-card-display/display-card-details.md).

# カード詳細を表示する

## 概要

このガイドでは、D1 SDK を使用して完全なカード情報（PAN、有効期限、カード所有者名、CVV2/dCVV2）を安全に表示する方法を説明します。

方法は 2 つあります:

* カード情報を取得し、イシュアアプリケーション UI で自分で表示します。
* データの露出を最小限に抑えるため、表示処理を D1 SDK に委任します。

{% hint style="warning" %}
PAN、有効期限、カード所有者名、または CVV2/dCVV2 を記録する可能性のあるログ、分析、クラッシュレポートは避けてください。必要なくなったらすぐに機密データをメモリから消去してください。
{% endhint %}

## ユーザーエクスペリエンス

<figure><img src="/files/2e47ca50eaf07d982cad0906bc3d8e4a7229ff65" alt=""><figcaption></figcaption></figure>

## オプション 1: カード情報を取得する

この方法では、イシュアアプリケーションが呼び出します `getCardDetails()` 完全なカード情報を取得し、それを表示する責任を負います。

機密性を保つため、D1 SDK は値をプレーンテキスト文字列ではなくバイト配列として返します。取得できる項目:

* PAN
* 有効期限
* カード所有者名（エンドユーザー）— 任意
* CVV2 または dCVV2

## シーケンス図

#### 前提条件:

* エンドユーザーとカードは D1 に登録されています。
* D1 SDK は正しく初期化されています。
* イシュアアプリケーションが D1 SDK のログイン API を呼び出しました。

<figure><img src="/files/31562edf159d6a766e2d4346c0df111aa9942e80" alt=""><figcaption></figcaption></figure>

### D1 SDK の統合

{% tabs %}
{% tab title="Android >= 4.4.0" %}

```kotlin
fun getCardDetails(d1Task: D1Task, cardID: String, activity: FragmentActivity) {
    activity.lifecycleScope.launch {
        try {
            val cardDetails = d1Task.secureCardDisplayService.getCardDetails(cardID).await()

            // サーバーから受け取った cardDetails オブジェクトを処理し、バイト配列型を文字列に変換します
            val cardHolderName: String? =
                cardDetails.cardHolderName?.let { String(it, Charsets.UTF_8) }
            val pan = String(cardDetails.pan, Charsets.UTF_8)
            val expiryDate = String(cardDetails.expiryDate, Charsets.UTF_8)
            val cvv = String(cardDetails.cvv, Charsets.UTF_8)

            // cardDetails オブジェクトのバイト配列変数を消去します
            cardDetails.wipe()
        } catch (exception: D1Exception) {
            // D1 SDK の統合 – エラー管理セクションを参照してください
        }
    }
}
```

{% endtab %}

{% tab title="Android < 4.4.0" %}

```kotlin
fun getCardDetails(d1Task: D1Task) {
            
  var cardID = "" // バックエンドから受け取ったカード ID
  val callback = object : D1Task.Callback<CardDetails> {
    
    override fun onSuccess(cardDetails: CardDetails) {
      // サーバーから受け取った cardDetails オブジェクトを処理し、バイト配列型を文字列に変換します。
      val cardHolderName: String? = cardDetails.cardHolderName?.let { String(it,Charsets.UTF_8) }
      val pan = String(cardDetails.pan, Charsets.UTF_8)
      val expiryDate = String(cardDetails.expiryDate, Charsets.UTF_8)
      val cvv = String(cardDetails.cvv, Charsets.UTF_8)
      // cardDetails オブジェクトのバイト配列変数を消去します。
      cardDetails.wipe()
    }

    override fun onError(exception: D1Exception) {
      // D1 SDK の統合 – エラー管理セクションを参照してください。
    }
  }

  d1Task.getCardDetails(cardID,callback)
}
```

{% endtab %}

{% tab title="iOS >= 4.4.0" %}

```swift
let cardID = "" // 例: サーバーから取得
do {
    let service = try d1Task.secureCardDisplayService()
    var cardDetails = try await service.cardDetails(cardID)
    // その後のフローを継続します。例: UI を更新
    print("有効期限: \((String(data: cardDetails.expiryDate, encoding: .utf8) ?? ""))")
    print("CVV: \((String(data: cardDetails.cvv, encoding: .utf8) ?? ""))")
    print("名前: \(String(data: cardDetails.cardHolderName ?? Data(), encoding: .utf8) ?? "")")
    print("PAN: \((String(data: cardDetails.pan, encoding: .utf8) ?? ""))")
    
    // 使用後、バイト配列の cardDetails を消去します
    cardDetails.wipe()
        
    
} catch let d1Error as D1Error {
    // D1 SDK の統合 – エラー管理セクションを参照してください
} catch let error {
    // その他のエラーを処理します
}
```

{% endtab %}

{% tab title="iOS < 4.4.0" %}

```swift
let cardID = "" // 例: サーバーから取得
d1Task.cardDetails(cardID) { cardDetails, error in
    if let error = error {
        // D1 SDK の統合 – エラー管理セクションを参照してください
    } else if var cardDetails = cardDetails {
        // その後のフローを継続します。例: UI を更新
        print("有効期限: \((String(data: cardDetails.expiryDate, encoding: .utf8) ?? ""))")
        print("CVV: \((String(data: cardDetails.cvv, encoding: .utf8) ?? ""))")
        print("名前: \(String(data: cardDetails.cardHolderName ?? Data(), encoding: .utf8) ?? "")")
        print("PAN: \((String(data: cardDetails.pan, encoding: .utf8) ?? ""))")

        // 使用後、バイト配列の cardDetails を消去します
        cardDetails.wipe()
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
カスタム UI/UX と表示ライフサイクルを完全に制御する必要があるイシュアに最適です。メモリ内の保持時間を最小限にし、 `wipe()` を使用後すぐに呼び出してください。
{% endhint %}

## オプション 2: 表示を D1 SDK に委任する

PAN の露出を減らすには、 `displayCardDetails`。ただし、 `getCardDetails`、この API はカードデータを返しません。代わりに、UI コンポーネントを `CardDetailsUI`として渡します。D1 SDK がそれらのテキスト内容を安全に設定します。イシュアアプリケーションはスタイルとレイアウトを完全に制御できます。

{% hint style="warning" %}
このオプションは Visa と Mastercard のカードのみをサポートします。PAN の長さと表示方法が異なるため、Amex カードはサポートしません。
{% endhint %}

`CardDetailsUI` 提供内容:

* `setPanMaskCharacter` は PAN マスク文字を設定するための `maskCardDetails` （デフォルト: `*`).
* `setPanSeparatorCharacter` は 4 桁ごとの PAN 区切り文字を設定します（デフォルト: スペース）。
* `setExpiryDateFormat` は有効期限の形式を設定します（デフォルト: `MM/YY`).
* `insecureCopyToClipboard` は PAN をシステムクリップボードにコピーします。推奨されません。

次の値を表示できます:

* PAN
* 有効期限
* カード所有者名（エンドユーザー）— 任意
* CVV2 または dCVV2

### シーケンス図

#### 前提条件:

* エンドユーザーとカードは D1 に登録されています。
* D1 SDK は正しく初期化されています。
* イシュアアプリケーションが D1 SDK のログイン API を呼び出しました。

<figure><img src="/files/2a1d638c37792868e1379f3de514dc7299fa8066" alt=""><figcaption><p>オプション 2 — D1 SDK が提供された UI コンポーネントにカード情報を表示します。</p></figcaption></figure>

`CardDetailsUI` を含みます `DisplayTextView` （Android）と `D1DisplayTextField` （iOS）、ネイティブの [TextView](https://developer.android.com/reference/android/widget/TextView) と [UITextField](https://developer.apple.com/documentation/uikit/uitextfield)。露出を抑えるため、 `getText()` は制限されています。

次を参照してください: [Android セキュリティ ガイドライン](/secure-card-display/ja/integrate-d1-sdk/deployment/security-guidelines/android-security-guidelines.md) を難読化するために `DisplayTextView`.

### D1 SDK の統合

{% tabs %}
{% tab title="Android >= 4.4.0" %}

```kotlin
fun displayCardDetails(d1Task: D1Task, cardID: String, cardDetailsUI: CardDetailsUI, activity: FragmentActivity) {
    activity.lifecycleScope.launch(Dispatchers.Main) {
        try {
            d1Task.secureCardDisplayService.displayCardDetails(cardID, cardDetailsUI)
                .await()
            // UI が更新されます
        } catch (exception: D1Exception) {
            // D1 SDK の統合 – エラー管理セクションを参照してください
        }
    }
    // UI が更新されます
}
```

{% endtab %}

{% tab title="Android < 4.4.0" %}

```kotlin
fun displayCardDetails (d1Task: D1Task) {

  var view: View? = null // レイアウトをここでインフレートします。
  val panTextView: DisplayTextView? = null // view?.findViewById(R.id.panText)
  val expiryDateTextView: DisplayTextView? = null //view?.findViewById(R.id.expiryDateText)
  val cvvTextView: DisplayTextView? = null //view?.findViewById(R.id.cvvText)
  val cardHolderNameTextView: DisplayTextView? = null //view?.findViewById(R.id.cardHolderNameText)

  val cardDetailsUI = CardDetailsUI.getInstance(panTextView, expiryDateTextView,
  cvvTextView, cardHolderNameTextView)

  var cardID = "" // バックエンドから受け取ったカード ID。
  val callback = object : D1Task.Callback<Void> {
      override fun onSuccess(ignore: Void?) {
        // UI が更新されます。
      }

      override fun onError(exception: D1Exception) {
        // D1 SDK の統合 – エラー管理セクションを参照してください。
      }
    }

  d1Task.displayCardDetails(cardID, cardDetailsUI, callback)
}
```

{% endtab %}

{% tab title="iOS >= 4.4.0" %}

```swift
let panTextField = D1DisplayTextField()
let cvvTextField = D1DisplayTextField()
let expiryDateTextField = D1DisplayTextField()
let cardHolderNameTextField = D1DisplayTextField()

/* 例: テキストフィールドをレイアウトします */

let cardDetailsUI = SecureCardDisplayService.CardDetailsUI(panTextField: panTextField,
                                                           expiryDateTextField: expiryDateTextField,
                                                           cvvTextField: cvvTextField,
                                                           cardHolderNameTextField: cardHolderNameTextField)

let cardID = "" // 例: サーバーから取得
do {
    let service = try d1Task.secureCardDisplayService()
    try await service.displayCardDetails(cardID, cardDetailsUI: cardDetailsUI)
} catch let d1Error as D1Error {
    // D1 SDK の統合 – エラー管理セクションを参照してください
} catch let error {
    // その他のエラーを処理します
}
```

{% endtab %}

{% tab title="iOS < 4.4.0" %}

```swift
let panTextField = D1DisplayTextField()
let cvvTextField = D1DisplayTextField()
let expiryDateTextField = D1DisplayTextField()
let cardHolderNameTextField = D1DisplayTextField()

/* 例: テキストフィールドをレイアウトします */

let cardDetailsUI = CardDetailsUI(panTextField: panTextField,
        expiryDateTextField: expiryDateTextField,
        cvvTextField: cvvTextField,
        cardHolderNameTextField: cardHolderNameTextField)

let cardID = "" // 例: サーバーから取得
d1Task.displayCardDetails(cardID, cardDetailsUI: cardDetailsUI) { error in
    if let error = error {
        // D1 SDK の統合 – エラー管理セクションを参照してください
    } else {
        // UI が更新されます
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
`insecureCopyToClipboard` PAN をシステム全体のクリップボードに公開するため、推奨されません。
{% endhint %}

### カード情報をマスクして表示する

便利なことに、 `CardDetailsUI` カード情報をマスクしたり表示したりできます:

* `maskCardDetails` 詳細をマスクします。
* `showCardDetails` 詳細を表示します。セキュリティ上、これは常にサーバーからデータを再取得します。

{% hint style="info" %}
ベストプラクティス: 短いタイマー（例: 1 分）を設定し、 `maskCardDetails` を呼び出して詳細を自動的に再マスクします。
{% endhint %}

{% tabs %}
{% tab title="Android >= 4.4.0" %}

```kotlin
fun showCardDetails(cardDetailsUI: CardDetailsUI, activity: FragmentActivity) {
        activity.lifecycleScope.launch {
            try {
                // カード情報をマスクします
                cardDetailsUI.maskCardDetails()

                // カード情報を再度表示します
                cardDetailsUI.showCardDetails().await()
                // UI が更新されます
            } catch (exception: D1Exception) {
                // D1 SDK の統合 – エラー管理セクションを参照してください
            }
    }
}
```

{% endtab %}

{% tab title="Android < 4.4.0" %}

```kotlin
fun showCardDetails (cardDetailsUI: CardDetailsUI) {
  // カード情報をマスクします。
  cardDetailsUI.maskCardDetails()

  val callback = object : D1Task.Callback<Void> {
    override fun onSuccess(ignore: Void?) {
      // UI が更新されます。
    }

    override fun onError(exception: D1Exception) {
      // D1 SDK の統合 – エラー管理セクションを参照してください。
    }
  }

  // カード情報を再度表示します。
  cardDetailsUI.showCardDetails(callback)
}
```

{% endtab %}

{% tab title="iOS >= 4.4.0" %}

```swift
// カード情報をマスクします
cardDetailsUI.maskCardDetails()

// カード情報を再度表示します
do {
    try await cardDetailsUI.showCardDetails()
    // その後のフローを継続します
} catch let d1Error as D1Error {
    // D1 SDK の統合 – エラー管理セクションを参照してください
} catch let error {
    // その他のエラーを処理します
}
```

{% endtab %}

{% tab title="iOS < 4.4.0" %}

<pre class="language-swift"><code class="lang-swift"><strong>// カード情報をマスクします
</strong>cardDetailsUI.maskCardDetails()

// カード情報を再度表示します
cardDetailsUI.showCardDetails() { error in
    if let error = error {
        // D1 SDK の統合 – エラー管理セクションを参照してください
    } else {
        // UI が更新されます
    }
}
</code></pre>

{% endtab %}
{% endtabs %}


---

# 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/secure-card-display/ja/implement-secure-card-display/display-card-details.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.
