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

# Autenticación en la app

{% hint style="danger" %}
Se requiere un servicio de tokenización para usar el flujo de "autenticación en la app" de Thales D1 SDK.
{% endhint %}

Al tokenizar una tarjeta en una billetera digital, de forma manual o desde la aplicación del emisor, es posible que se requiera una autenticación reforzada del usuario final.

Entre las diferentes opciones de ID\&V ofrecidas por el emisor al usuario final, el escenario de autenticación en la app depende de la aplicación del emisor para verificar la identidad del usuario final.

Es posible usar D1 SDK para activar la tarjeta digital después de una autenticación exitosa.

La aplicación del emisor **debe**, primero, integrarse correctamente con el proveedor de la billetera y reconocer, a partir de la llamada de Wallet, la tarjeta para la cual se requiere la autenticación.

Esto se describe en detalle para cada plataforma en la sección [Integrar ID\&V en la app para billeteras xPay](/push-provisioning/es/integrate-in-app-id-and-v-for-xpay-wallets.md) .

## Flujo de autenticación en la app

**Prerrequisitos**

* El usuario final, la cuenta y la tarjeta fueron registrados en D1
* SDK está correctamente inicializado

<figure><img src="/files/71a27e33026313d6570eb3408b86aef8ef133653" alt=""><figcaption></figcaption></figure>

{% stepper %}
{% step %}

#### Identificar la tarjeta

Identificar la tarjeta para la cual se requiere la autenticación (descrito en [Integrar ID\&V en la app para billeteras xPay](/push-provisioning/es/integrate-in-app-id-and-v-for-xpay-wallets.md)).
{% endstep %}

{% step %}

#### Autenticar al usuario final

Autenticar al usuario final y generar un `accessToken` como se define en el [flujo de inicio de sesión en D1 SDK](/push-provisioning/es/integrate-the-d1-sdk/getting-started/configuration/5.-authentication/sdk-login.md) para autorizar la activación de la tarjeta.
{% endstep %}

{% step %}

#### Activar la tarjeta con D1 SDK

Llamar a la API de D1 SDK `activateDigitalCard` con `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:\))) para activar la tarjeta.
{% endstep %}
{% endstepper %}

Desde D1 SDK V3.2.0, D1 SDK proporciona una nueva API para activar la tarjeta digital. Ejemplos específicos de la plataforma:

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

```kotlin
//digitalCardID: Analizado a partir de EXTRA_TEXT proveniente de la app de la billetera.
fun activeDigitalCard(d1Task: D1Task, digitalCardID: String) {
    //Llamar a D1PushWallet.activateDigitalCard para activar la tarjeta.
    d1Task.d1PushWallet.activateDigitalCard(
        digitalCardID,
        object : D1Task.Callback<Void?> {
            override fun onSuccess(data: Void?) {
                Log.w(TAG, "Activación de tarjeta - HECHO")
                //Muestra el resultado de la activación al usuario.
                //Tras la confirmación del usuario, redirige al usuario de vuelta a Google Wallet.
            }

            override fun onError(exception: D1Exception) {
                //Muestra el resultado de la activación al usuario.
            }
        }
    )
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
let digitalCardID = ""  // obtenido de PKPass
d1Task.activateDigitalCard(withDigitalCardID: digitalCardID) { error in
    if let error = error {
        // Gestionar el error
    } else {
        // Continuar con los flujos posteriores. Por ejemplo, actualizar la interfaz de usuario.
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
El `deviceAccountIdentifier` corresponde al `digitalCardId` en D1 y este ID se puede usar para activar la tarjeta digital.

`primaryAccountNumberSuffix` son los últimos cuatro dígitos del PAN que se ha tokenizado. Esto se puede usar para recuperar la imagen de la tarjeta y mostrarla al usuario final para la solicitud de autenticación.
{% endhint %}

### Apple Pay

Desde D1 SDK V3.2.0, D1 SDK ha proporcionado una [digitalCardPass](https://thalesgroup.github.io/d1sdk-docs/d1-sdk/4.3.0/ios/documentation/d1/d1task/digitalcardpass\(forserialnumber:\)) API para que el integrador obtenga los pases de la tarjeta digital basándose en los números de serie respectivos.

```swift
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
        // gestionar el error, por ejemplo, registrándolo
        return false
    }
    
    guard let queryItems = components.queryItems else {
        // gestionar el error, por ejemplo, registrándolo
        return false
    }

    // ejemplo de comprobación de los elementos de consulta
    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 {
        // gestionar el error, por ejemplo, mostrando una interfaz de error
        return false
    }

    guard let serialNumber = queryItems[indexSerialNumber].value else {
        // gestionar el error, por ejemplo, mostrando una interfaz de error
        return false
    }

    do {
        guard let pkPass = try d1Task.digitalCardPass(forSerialNumber: serialNumber) else {
            // gestionar el error, por ejemplo, mostrando una interfaz de error
            return false
        }

        guard let deviceAccountIdentifier = pkPass.secureElementPass?.deviceAccountIdentifier,
              let primaryAccountNumberSuffix = pkPass.secureElementPass?.primaryAccountNumberSuffix else {
            // gestionar el error, por ejemplo, mostrando una interfaz de error
            return false
        }

        // mostrar primaryAccountNumberSuffix para la interfaz de confirmación

        // continuar con la activación de la tarjeta
        let digitalCardID = deviceAccountIdentifier
        d1Task.activateDigitalCard(withDigitalCardID: digitalCardID) { error in
            if let error = error {
                // gestionar el error, por ejemplo, mostrando una interfaz de error
            } else {
                // mostrar el resultado de la activación al usuario.
            }
        }

        return true
    } catch {
        // gestionar el error, por ejemplo, mostrando una interfaz de error
        return false
    }
}
```

### Google y Samsung Pay

Para completar la activación, la aplicación del emisor debe iniciar un contexto de actividad para completar la activación del token usando los parámetros de activación pasados en el `Intent`.

```kotlin
/*
 * Dentro de la aplicación móvil del emisor AppToAppActivity (CardActivationActivity)
 * biblioteca adicional: com.fasterxml.jackson.core:jackson-core y 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) {
    /*
     * Después de recibir el intent, la aplicación debe usar la API Activity.getCallingPackage() para
     * validar que la solicitud proviene de Google Pay o Samsung Pay de la siguiente manera:
     */
    // Valida si el llamador es Google Wallet (Google Play Services) o Samsung Pay
    if ("com.google.android.gms".equals(getCallingPackage()) ||
        "com.samsung.android.spay".equals(getCallingPackage())) {
        // Procede con la activación del token.
    } else {
        // Aborta la activación del token: gestionar el error.
    }

    val data: String? = activity.getIntent().getStringExtra(Intent.EXTRA_TEXT)
    if (data == null){
        // Abortar la activación del token: gestionar el error
    }

    try {
        // Analiza base64 para recuperar los parámetros de activación como un objeto JSON en una cadena.
        val decodedDataBytes = Base64.decode(data, Base64.DEFAULT)
        val decodedData = String(decodedDataBytes, StandardCharsets.UTF_8)

        // Lee la cadena JSON usando Jackson.
        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) { // Esquema VISA
            // Para VISA -> tokenReferenceID : digitalCardId.
            digitalCardId = node["tokenReferenceID"].asText() // VISA
            panLast4 = node["panLast4"].asText() // VISA

            // tokenRequestorId -> "40010075001" para Google Pay o "40010043095" para Samsung Pay.
            // Esto es relevante solo en caso de que SCHEME sea VISA. Para MASTERCARD, poner cadena vacía.
            tokenRequestorId = node["tokenRequestorID"].asText() // VISA

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

        // Nota: la aplicación debe mostrar panLast4 como identificación de la tarjeta.

        // Iniciar sesión antes de activar la tarjeta digital.

        // Llamar a D1PushWallet.activateDigitalCard para activar la tarjeta.
        d1Task.d1PushWallet.activateDigitalCard(
            digitalCardId,
            object : D1Task.Callback<Void?> {
                override fun onSuccess(data: Void?) {
                    Log.w(TAG, "Activación de tarjeta - HECHO");
                    // Muestra el resultado de la activación al usuario.
                    // Tras la confirmación del usuario, redirige al usuario de vuelta a Google Wallet.
                    sendResultToWalletApp(activity, null)
                }

                override fun onError(exception: D1Exception) {
                    // Muestra el resultado de la activación al usuario.
                    sendResultToWalletApp(activity, exception)
                }
            }
        )
    } catch (exception: IOException) {
        // Aborta la activación del token: gestionar el error.
    }
}

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

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

#### Actualización del estado de Google Pay Wallet

Se recomienda que la aplicación del emisor se registre para los cambios de estado de la billetera de Google Pay, de modo que pueda actualizar el estado más reciente de la billetera/tarjeta en la interfaz de usuario.

Estos cambios incluyen:

* Cuando cambia la billetera activa (al cambiar la cuenta activa).
* Cuando cambia la tarjeta seleccionada de la billetera activa.
* Cuando se agregan o eliminan tarjetas tokenizadas de la billetera activa.
* Cuando cambia el estado de un token en la billetera activa.

```kotlin
fun updateGooglePayWalletState(d1Task: D1Task) {
    // El registro del callback debe hacerse lo antes posible, por ejemplo, justo después de que d1Task.configure() se complete correctamente.
    d1Task.registerCardDataChangedListener {
        // Actualizar aquí el estado/la información de la tarjeta.
    }

    // La anulación del registro del callback debe ocurrir cuando el usuario final salga de la aplicación
    d1Task.unRegisterCardDataChangedListener()
}
```

{% hint style="info" %}
Solo las aplicaciones en primer plano recibirán notificaciones de los eventos de cambio de datos. Por lo tanto, cada aplicación debe actualizar los estados de los tokens no solo al recibir actualizaciones del callback, sino también cuando la aplicación se inicia o vuelve al primer plano.
{% endhint %}

Para obtener acceso completo a D1 SDK, consulte [referencia de API](/push-provisioning/es/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/es/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.
