> 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 SDK D1 de Thales para el flujo de "autenticación en la aplicación".
{% endhint %}

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

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

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

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

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

## Flujo de autenticación en la aplicación

**Requisitos previos**

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

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

{% stepper %}
{% step %}

#### Identificar la tarjeta

Identificar la tarjeta para la que se requiere la autenticación (descrito en [Integrar ID\&V en la aplicación para carteras 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` según lo definido en el [flujo de inicio de sesión en el SDK D1](/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 el SDK D1

Llamar a la API del SDK D1 `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 ofrece 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 procedente de la aplicación de la cartera.
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, "Card Activation - DONE")
                //Muestra el resultado de la activación al usuario.
                //Tras el reconocimiento del usuario, redirigir 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 {
        // Gestiona el error
    } else {
        // Continuar con los flujos posteriores. Por ejemplo, actualizar la UI.
    }
}
```

{% 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 tarjeta digital basándose en los respectivos números de serie.

```swift
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    guard let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else {
        // manejar error, por ejemplo, registro
        return false
    }
    
    guard let queryItems = components.queryItems else {
        // manejar error, por ejemplo, registro
        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 {
        // manejar error, por ejemplo, mostrar UI de error
        return false
    }

    guard let serialNumber = queryItems[indexSerialNumber].value else {
        // manejar error, por ejemplo, mostrar UI de error
        return false
    }

    do {
        guard let pkPass = try d1Task.digitalCardPass(forSerialNumber: serialNumber) else {
            // manejar error, por ejemplo, mostrar UI de error
            return false
        }

        guard let deviceAccountIdentifier = pkPass.secureElementPass?.deviceAccountIdentifier,
              let primaryAccountNumberSuffix = pkPass.secureElementPass?.primaryAccountNumberSuffix else {
            // manejar error, por ejemplo, mostrar UI de error
            return false
        }

        // mostrar primaryAccountNumberSuffix para la UI de confirmación

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

        return true
    } catch {
        // manejar error, por ejemplo, mostrar UI 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 utilizando los parámetros de activación pasados en el `Intent`.

```kotlin
/*
 * Dentro de la AppToAppActivity de la aplicación móvil del emisor (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: manejar error.
    }

    val data: String? = activity.getIntent().getStringExtra(Intent.EXTRA_TEXT)
    if (data == null){
        // Abortar la activación del token: manejar 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 solo es relevante en caso de que SCHEME sea VISA. Para MASTERCARD, dejar la 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, "Card Activation - DONE");
                    // Muestra el resultado de la activación al usuario.
                    // Tras el reconocimiento del usuario, redirigir 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: manejar 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 la cartera de Google Pay

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

Estos cambios incluyen:

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

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

    // La desregistración de la devolución de llamada debe ocurrir cuando el usuario final sale de la aplicación
    d1Task.unRegisterCardDataChangedListener()
}
```

{% hint style="info" %}
Solo las aplicaciones en primer plano serán notificadas 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 de la devolución de llamada, sino también cuando la aplicación se inicia o vuelve al primer plano.
{% endhint %}

Para obtener acceso completo al SDK de D1, consulte [referencia de la 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, and the optional `goal` query parameter:

```
GET https://docs.payments.thalescloud.io/push-provisioning/es/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.
