> 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/push-provisioning/ja/implement-push-provisioning/implement-view-and-control/in-app-authentication.md).

# アプリ内認証

{% hint style="danger" %}
「アプリ内認証」フローで Thales D1 SDK を使用するには、トークナイゼーションサービスが必要です。
{% endhint %}

デジタルウォレットでカードをトークン化する際、手動でもイシュアアプリケーションからでも、エンドユーザー認証のステップアップが必要になる場合があります。

イシュアがエンドユーザーに提供するさまざまな ID\&V オプションのうち、アプリ内認証シナリオは、エンドユーザーの本人確認をイシュアアプリケーションに依存します。

認証が成功した後に、D1 SDK を使用してデジタルカードを有効化できます。

イシュアアプリ **必須**、まず、ウォレットプロバイダーと適切に連携し、Wallet 呼び出しから、認証が必要なカードを認識する必要があります。

これは、各プラットフォームについて [xPay ウォレット向けアプリ内 ID\&V の統合](/push-provisioning/ja/integrate-in-app-id-and-v-for-xpay-wallets.md) セクションで詳しく説明されています。

## アプリ内認証フロー

**前提条件**

* エンドユーザー、アカウント、およびカードが D1 に登録されている
* SDK が適切に初期化されている

<figure><img src="/files/75d0a7ede1fb802f96989db2c685b66df4b46d7b" alt=""><figcaption></figcaption></figure>

{% stepper %}
{% step %}

#### カードを識別する

認証が必要なカードを識別します（ [xPay ウォレット向けアプリ内 ID\&V の統合](/push-provisioning/ja/integrate-in-app-id-and-v-for-xpay-wallets.md)).
{% endstep %}

{% step %}

#### エンドユーザーを認証する

エンドユーザーを認証し、 `accessToken` を生成します。これは、 [D1 SDK へのログインフロー](/push-provisioning/ja/integrate-the-d1-sdk/getting-started/configuration/5.-authentication/sdk-login.md) で定義されており、カードの有効化を認可するためのものです。
{% endstep %}

{% step %}

#### D1 SDK でカードを有効化する

D1 SDK API `activateDigitalCard` を `digitalCardID` ([Android](https://thalesgroup.github.io/d1sdk-docs/d1-sdk/latest/android/com/thalesgroup/gemalto/d1/card/D1PushWallet.html#activateDigitalCard\(java.lang.String,com.thalesgroup.gemalto.d1.D1Task.Callback\))/[iOS](https://thalesgroup.github.io/d1sdk-docs/d1-sdk/4.3.0/ios/documentation/d1/d1task/activatedigitalcard\(withdigitalcardid:completion:\))) を使用して呼び出し、カードを有効化します。
{% endstep %}
{% endstepper %}

D1 SDK V3.2.0 以降、D1 SDK はデジタルカードを有効化するための新しい API を提供しています。プラットフォーム固有の例：

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

```kotlin
//digitalCardID: ウォレットアプリから渡される EXTRA_TEXT から解析されます。
fun activeDigitalCard(d1Task: D1Task, digitalCardID: String) {
    //カードを有効化するために D1PushWallet.activateDigitalCard を呼び出します。
    d1Task.d1PushWallet.activateDigitalCard(
        digitalCardID,
        object : D1Task.Callback<Void?> {
            override fun onSuccess(data: Void?) {
                Log.w(TAG, "カード有効化 - 完了")
                //有効化結果をユーザーに表示します。
                //ユーザーの確認後、ユーザーを Google Wallet にリダイレクトします。
            }

            override fun onError(exception: D1Exception) {
                //有効化結果をユーザーに表示します。
            }
        }
    )
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
let digitalCardID = ""  // PKPass から取得
d1Task.activateDigitalCard(withDigitalCardID: digitalCardID) { error in
    if let error = error {
        // エラーを処理
    } else {
        //後続のフローに進みます。たとえば、UI を更新します。
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
この `deviceAccountIdentifier` は `digitalCardId` （D1 内）に対応しており、この ID を使用してデジタルカードを有効化できます。

`primaryAccountNumberSuffix` は、トークン化された PAN の下4桁です。これは、カードデザインを取得して、認証リクエスト用にエンドユーザーへ表示するために使用できます。
{% endhint %}

### Apple Pay

D1 SDK V3.2.0 以降、D1 SDK は、 [digitalCardPass](https://thalesgroup.github.io/d1sdk-docs/d1-sdk/4.3.0/ios/documentation/d1/d1task/digitalcardpass\(forserialnumber:\)) API を提供しており、インテグレーターはそれぞれのシリアル番号に基づいてデジタルカードパスを取得できます。

```swift
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
        // エラーを処理 例: ログ出力
        return false
    }
    
    guard let queryItems = components.queryItems else {
        // エラーを処理 例: ログ出力
        return false
    }

    // クエリアイテムを確認する例
    let containsPassTypeIdentifier = queryItems.contains(where: { $0.name == "passTypeIdentifier" && $0.value == "paymentpass.com.apple" })
    let indexSerialNumber = queryItems.firstIndex(where: { $0.name == "serialNumber" })
    let containsAction = queryItems.contains(where: { $0.name == "action" })
    let validated = containsPassTypeIdentifier && indexSerialNumber != nil && containsAction

    guard validated, let indexSerialNumber = indexSerialNumber else {
        // エラーを処理 例: エラー UI を表示
        return false
    }

    guard let serialNumber = queryItems[indexSerialNumber].value else {
        // エラーを処理 例: エラー UI を表示
        return false
    }

    do {
        guard let pkPass = try d1Task.digitalCardPass(forSerialNumber: serialNumber) else {
            // エラーを処理 例: エラー UI を表示
            return false
        }

        guard let deviceAccountIdentifier = pkPass.secureElementPass?.deviceAccountIdentifier,
              let primaryAccountNumberSuffix = pkPass.secureElementPass?.primaryAccountNumberSuffix else {
            // エラーを処理 例: エラー UI を表示
            return false
        }

        // 確認 UI 用に primaryAccountNumberSuffix を表示

        // カード有効化を続行
        let digitalCardID = deviceAccountIdentifier
        d1Task.activateDigitalCard(withDigitalCardID: digitalCardID) { error in
            if let error = error {
                // エラーを処理 例: エラー UI を表示
            } else {
                // 有効化結果をユーザーに表示します。
            }
        }

        return true
    } catch {
        // エラーを処理 例: エラー UI を表示
        return false
    }
}
```

### Google & Samsung Pay

有効化を完了するには、イシュアアプリがアクティビティコンテキストを開始し、渡された有効化パラメータを使用してトークンの有効化を完了する必要があります。 `Intent`.

```kotlin
/*
 * イシュアのモバイルアプリ内 AppToAppActivity (CardActivationActivity)
 * 追加ライブラリ: com.fasterxml.jackson.core:jackson-core & com.fasterxml.jackson.core:jackson-databind
 * import android.util.Base64;
 * import com.fasterxml.jackson.databind.JsonNode;
 * import com.fasterxml.jackson.databind.ObjectMapper;
 */
fun activeDigitalCard_inAppAuthentication(d1Task: D1Task, activity: Activity) {
    /*
     * Intent を受信した後、アプリケーションは Activity.getCallingPackage() API を使用して
     * リクエストが次のように Google Pay または Samsung Pay から来ていることを検証する必要があります:
     */
    // 呼び出し元が Google Wallet（Google Play Services）または Samsung Pay かどうかを検証します
    if ("com.google.android.gms".equals(getCallingPackage()) ||
        "com.samsung.android.spay".equals(getCallingPackage())) {
        // トークンの有効化を続行します。
    } else {
        // トークンの有効化を中止: エラーを処理します。
    }

    val data: String? = activity.getIntent().getStringExtra(Intent.EXTRA_TEXT)
    if (data == null){
        // トークンの有効化を中止: エラーを処理
    }

    try {
        // base64 を解析し、文字列内の JSON オブジェクトとして有効化パラメータを取得します。
        val decodedDataBytes = Base64.decode(data, Base64.DEFAULT)
        val decodedData = String(decodedDataBytes, StandardCharsets.UTF_8)

        // Jackson を使用して JSON 文字列を読み取ります。
        val mapper = ObjectMapper()
        val node = mapper.readTree(decodedData)

        var digitalCardId: String = ""
        var scheme = CardScheme.VISA.scheme
        var panLast4: String = ""
        var tokenRequestorId: String = ""

        if (node["tokenReferenceID"] != null) { // VISA スキーム
            // VISA の場合 -> tokenReferenceID : digitalCardId。
            digitalCardId = node["tokenReferenceID"].asText() // VISA
            panLast4 = node["panLast4"].asText() // VISA

            // tokenRequestorId -> Google Pay の場合は "40010075001"、Samsung Pay の場合は "40010043095"。
            // これは SCHEME が VISA の場合にのみ関連します。MASTERCARD の場合は空文字列を設定します。
            tokenRequestorId = node["tokenRequestorID"].asText() // VISA

        } else { // MASTERCARD
            // MasterCard の場合 -> tokenUniqueReference : D1 -> digitalCardId。
            digitalCardId = node["tokenUniqueReference"].asText() // MasterCard
            panLast4 = node["accountPanSuffix"].asText() // MasterCard
            scheme = CardScheme.MASTERCARD.scheme
        }

        // 注: アプリケーションは panLast4 をカード識別として表示する必要があります。

        // デジタルカードを有効化する前にログインします。

        // カードを有効化するために D1PushWallet.activateDigitalCard を呼び出します。
        d1Task.d1PushWallet.activateDigitalCard(
            digitalCardId,
            object : D1Task.Callback<Void?> {
                override fun onSuccess(data: Void?) {
                    Log.w(TAG, "カード有効化 - 完了");
                    // 有効化結果をユーザーに表示します。
                    // ユーザーの確認後、ユーザーを Google Wallet にリダイレクトします。
                    sendResultToWalletApp(activity, null)
                }

                override fun onError(exception: D1Exception) {
                    // 有効化結果をユーザーに表示します。
                    sendResultToWalletApp(activity, exception)
                }
            }
        )
    } catch (exception: IOException) {
        // トークンの有効化を中止: エラーを処理します。
    }
}

private fun sendResultToWalletApp(activity: Activity, exception: D1Exception?) {
    val resultIntent = Intent()
    // "approved"、または "failure"
    resultIntent.putExtra("BANKING_APP_ACTIVATION_RESPONSE",if (exception == null) "approved" else "failure")

    activity.setResult(Activity.RESULT_OK, resultIntent)
    activity.finish()
}
```

#### Google Pay Wallet 状態更新

イシュアアプリケーションは、UI 上でウォレット/カードの最新ステータスを更新できるよう、Google Pay ウォレットの状態変更に登録することが推奨されます。

これらの変更には次が含まれます:

* アクティブなウォレットが変更されたとき（アクティブアカウントの変更による）。
* アクティブなウォレットの選択カードが変更されたとき。
* トークン化されたカードがアクティブなウォレットに追加または削除されたとき。
* アクティブなウォレット内のトークンのステータスが変更されたとき。

```kotlin
fun updateGooglePayWalletState(d1Task: D1Task) {
    // コールバックの登録は、たとえば d1Task.configure() が成功した直後など、できるだけ早く行う必要があります。
    d1Task.registerCardDataChangedListener {
        // ここでカードステータス/情報を更新します。
    }

    // コールバックの登録解除は、エンドユーザーがアプリを終了するときに行う必要があります
    d1Task.unRegisterCardDataChangedListener()
}
```

{% hint style="info" %}
データ変更イベントはフォアグラウンドのアプリケーションにのみ通知されます。したがって、各アプリケーションは、コールバックから更新を受け取るだけでなく、アプリケーションの起動時またはフォアグラウンドに戻ったときにもトークンステータスを更新する必要があります。
{% endhint %}

D1 SDK への完全なアクセスについては、 [API リファレンス](/push-provisioning/ja/integrate-the-d1-sdk/api-reference.md).


---

# 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:

```
GET https://docs.payments.thalescloud.io/push-provisioning/ja/implement-push-provisioning/implement-view-and-control/in-app-authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
