> 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 を「in-app authentication」フローで使用するには、トークナイゼーションサービスが必要です。
{% endhint %}

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

イシュアがエンドユーザーに提供するさまざまな ID\&V オプションの中で、in-app authentication シナリオでは、エンドユーザーの本人確認のためにイシュアアプリケーションに依存します。

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

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

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

## アプリ内認証フロー

**前提条件**

* エンドユーザー、アカウント、カードは D1 に登録済みです
* SDK は正しく初期化されています

<figure><img src="https://1486457345-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FWDlYTPaq4dNHuiWtf8ux%2Fuploads%2FL7uyQy8eyg0Vq5eKCeqr%2FSequence%20Diagram%20-%20In%20app%20authentication.svg?alt=media&amp;token=ac02abc5-fc0f-4719-9d9d-b8e5ad1cb35d" alt=""><figcaption></figcaption></figure>

{% stepper %}
{% step %}

#### カードを特定する

認証が必要なカードを特定します（ [xPay Wallets 向け in-app 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 には、デジタルカードを有効化するための新しい 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 >= 4.5.0" %}

```swift
let digitalCardID = ""  // PKPass から取得
do {
    let service = try d1Task.digitalCardService()
    try await service.activateDigitalCard(withDigitalCardID: digitalCardID)
} catch let d1Error as D1Error {
    // D1 SDK 統合 – エラー管理セクションを参照してください
} catch let error {
    //その他のエラーを処理
}
```

{% endtab %}

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

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

{% endtab %}
{% endtabs %}

{% hint style="info" %}
The `deviceAccountIdentifier` は `digitalCardId` に対応し、この 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 を提供しています。

{% tabs %}
{% tab title="iOS >= 4.5.0" %}

```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 {
            let service = try d1Task.pushProvisioningService()
            guard let pkPass = try service.digitalCard(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
            Task {
                do {
                    let service = try d1Task.digitalCardService()
                    try await service.activateDigitalCard(withDigitalCardID: digitalCardID)
                } catch let d1Error as D1Error {
                    // D1 SDK 統合 – エラー管理セクションを参照してください
                } catch let error {
                    //その他のエラーを処理
                }
            }
            return true
        } catch {
            //エラーを処理します。たとえばエラー UI を表示
            return false
        }
    }
```

{% endtab %}

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

```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
    }
}
```

{% endtab %}
{% endtabs %}

### 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 Scheme
            // 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 ウォレット状態の更新

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

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

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

```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, and the optional `goal` query parameter:

```
GET https://docs.payments.thalescloud.io/push-provisioning/ja/implement-push-provisioning/implement-view-and-control/in-app-authentication.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.
