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

# Mostrar detalles de la tarjeta

## Descripción general

Esta guía explica cómo mostrar de forma segura los detalles completos de la tarjeta (PAN, fecha de vencimiento, nombre del titular y CVV2/dCVV2) con el SDK D1.

Tiene dos enfoques:

* Obtenga los detalles de la tarjeta y muéstrelos usted mismo en la interfaz de usuario de la aplicación emisora.
* Delegue el renderizado al SDK D1 para minimizar la exposición de datos.

{% hint style="warning" %}
Evite el registro, la analítica o los informes de fallos que puedan capturar el PAN, la fecha de vencimiento, el nombre del titular o CVV2/dCVV2. Borre siempre los datos confidenciales de la memoria tan pronto como ya no sean necesarios.
{% endhint %}

## Experiencia de usuario

<figure><img src="/files/e6c44550e52bb33ec3cb0ac316fb38f3d3597e77" alt=""><figcaption></figcaption></figure>

## Opción 1: obtener los detalles de la tarjeta

En este enfoque, la aplicación emisora llama a `getCardDetails()` para recuperar la información completa de la tarjeta y es responsable de mostrarla.

Para proteger la confidencialidad, el SDK D1 devuelve los valores como matrices de bytes en lugar de cadenas de texto plano. Puede recuperar:

* PAN
* Fecha de vencimiento
* Nombre del titular (usuario final) — opcional
* CVV2 o dCVV2

## Diagrama de secuencia

#### Requisitos previos:

* El usuario final y las tarjetas están registrados en D1.
* El SDK D1 está inicializado correctamente.
* La aplicación emisora llamó a la API de inicio de sesión del SDK D1.

<figure><img src="/files/63ec418d3b1a6ea181d4db09c74fddcd7a1bc01c" alt=""><figcaption></figcaption></figure>

### Integración del SDK D1

{% 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()

            // manejar el objeto cardDetails del servidor, convertir el tipo de matriz de bytes a cadena
            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)

            // borrar las variables de matriz de bytes del objeto cardDetails
            cardDetails.wipe()
        } catch (exception: D1Exception) {
            // Consulte la sección Integración del SDK D1 – Gestión de errores
        }
    }
}
```

{% endtab %}

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

```kotlin
fun getCardDetails(d1Task: D1Task) {
            
  var cardID = "" // id de tarjeta recibido del backend
  val callback = object : D1Task.Callback<CardDetails> {
    
    override fun onSuccess(cardDetails: CardDetails) {
      // Maneja el objeto cardDetails del servidor, convierte el tipo de matriz de bytes a cadena.
      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)
      // Borra las variables de matriz de bytes del objeto cardDetails.
      cardDetails.wipe()
    }

    override fun onError(exception: D1Exception) {
      // Consulte la sección Integración del SDK D1 – Gestión de errores.
    }
  }

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

{% endtab %}

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

```swift
let cardID = "" // obtenido, por ejemplo, del servidor
do {
    let service = try d1Task.secureCardDisplayService()
    var cardDetails = try await service.cardDetails(cardID)
    // Continúe con los flujos posteriores, por ejemplo, actualizar la interfaz de usuario
    print("Exp: \((String(data: cardDetails.expiryDate, encoding: .utf8) ?? ""))")
    print("CVV: \((String(data: cardDetails.cvv, encoding: .utf8) ?? ""))")
    print("Name: \(String(data: cardDetails.cardHolderName ?? Data(), encoding: .utf8) ?? "")")
    print("PAN: \(String(data: cardDetails.pan, encoding: .utf8) ?? ""))")
    
    // después de usarlo, borre la matriz de bytes cardDetails
    cardDetails.wipe()
        
    
} catch let d1Error as D1Error {
    // Consulte la sección Integración del SDK D1 – Gestión de errores
} catch let error {
    // Manejar otro error
}
```

{% endtab %}

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

```swift
let cardID = "" // obtenido, por ejemplo, del servidor
d1Task.cardDetails(cardID) { cardDetails, error in
    if let error = error {
        // Consulte la sección Integración del SDK D1 – Gestión de errores
    } else if var cardDetails = cardDetails {
        // Continúe con los flujos posteriores, por ejemplo, actualizar la interfaz de usuario
        print("Exp: \((String(data: cardDetails.expiryDate, encoding: .utf8) ?? ""))")
        print("CVV: \((String(data: cardDetails.cvv, encoding: .utf8) ?? ""))")
        print("Name: \(String(data: cardDetails.cardHolderName ?? Data(), encoding: .utf8) ?? "")")
        print("PAN: \(String(data: cardDetails.pan, encoding: .utf8) ?? ""))")

        // después de usarlo, borre la matriz de bytes cardDetails
        cardDetails.wipe()
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Mejor para emisores que necesitan una UI/UX personalizada y control total sobre el ciclo de vida del renderizado. Asegúrese de minimizar el tiempo de permanencia en memoria y llamar a `wipe()` inmediatamente después de usarlo.
{% endhint %}

## Opción 2: delegar la visualización al SDK D1

Para reducir la exposición del PAN, use `displayCardDetails`. A diferencia de `getCardDetails`, esta API no devuelve datos de la tarjeta. En su lugar, pasa componentes de la interfaz de usuario mediante `CardDetailsUI`, y el SDK D1 establece de forma segura el contenido de texto de estos. La aplicación emisora conserva el control total sobre el estilo y el diseño.

{% hint style="warning" %}
Esta opción solo admite tarjetas Visa y Mastercard. No admite tarjetas Amex porque la longitud del PAN y el renderizado difieren.
{% endhint %}

`CardDetailsUI` proporciona:

* `setPanMaskCharacter` para establecer el carácter de máscara del PAN para `maskCardDetails` (predeterminado: `*`).
* `setPanSeparatorCharacter` para establecer el separador del PAN cada 4 dígitos (predeterminado: espacio).
* `setExpiryDateFormat` para establecer el formato de la fecha de vencimiento (predeterminado: `MM/YY`).
* `insecureCopyToClipboard` para copiar el PAN al portapapeles del sistema. No recomendado.

Se pueden mostrar los siguientes valores:

* PAN
* Fecha de vencimiento
* Nombre del titular (usuario final) — opcional
* CVV2 o dCVV2

### Diagrama de secuencia

#### Requisitos previos:

* El usuario final y las tarjetas están registrados en D1.
* El SDK D1 está inicializado correctamente.
* La aplicación emisora llamó a la API de inicio de sesión del SDK D1.

<figure><img src="/files/ff1ca4b2d33141044d2b5244db9c5bbe54d44d56" alt=""><figcaption><p>Opción 2 — El SDK D1 muestra los detalles de la tarjeta en los componentes de interfaz de usuario proporcionados.</p></figcaption></figure>

`CardDetailsUI` contiene `DisplayTextView` (Android) y `D1DisplayTextField` (iOS), que heredan de forma nativa de [TextView](https://developer.android.com/reference/android/widget/TextView) y [UITextField](https://developer.apple.com/documentation/uikit/uitextfield). Para limitar la exposición, `getText()` está restringido.

Consulte las [directrices de seguridad de Android](/secure-card-display/es/integrate-d1-sdk/deployment/security-guidelines/android-security-guidelines.md) para ofuscar `DisplayTextView`.

### Integración del SDK D1

{% 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()
            // La interfaz de usuario se actualiza
        } catch (exception: D1Exception) {
            // Consulte la sección Integración del SDK D1 – Gestión de errores
        }
    }
    // La interfaz de usuario se actualiza
}
```

{% endtab %}

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

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

  var view: View? = null // Infle su diseño aquí.
  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 de tarjeta recibido del backend.
  val callback = object : D1Task.Callback<Void> {
      override fun onSuccess(ignore: Void?) {
        // La interfaz de usuario se actualiza.
      }

      override fun onError(exception: D1Exception) {
        // Consulte la sección Integración del SDK D1 – Gestión de errores.
      }
    }

  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()

/* por ejemplo, organice los campos de texto */

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

let cardID = "" // obtenido, por ejemplo, del servidor
do {
    let service = try d1Task.secureCardDisplayService()
    try await service.displayCardDetails(cardID, cardDetailsUI: cardDetailsUI)
} catch let d1Error as D1Error {
    // Consulte la sección Integración del SDK D1 – Gestión de errores
} catch let error {
    // Manejar otro error
}
```

{% endtab %}

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

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

/* por ejemplo, organice los campos de texto */

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

let cardID = "" // obtenido, por ejemplo, del servidor
d1Task.displayCardDetails(cardID, cardDetailsUI: cardDetailsUI) { error in
    if let error = error {
        // Consulte la sección Integración del SDK D1 – Gestión de errores
    } else {
        // La interfaz de usuario se actualiza
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
`insecureCopyToClipboard` expone el PAN al portapapeles de todo el sistema y no se recomienda.
{% endhint %}

### Enmascarar y mostrar los detalles de la tarjeta

Para mayor comodidad, `CardDetailsUI` le permite enmascarar y mostrar los detalles de la tarjeta:

* `maskCardDetails` enmascara los detalles.
* `showCardDetails` muestra los detalles. Por seguridad, siempre vuelve a obtener los datos del servidor.

{% hint style="info" %}
Mejor práctica: establezca un temporizador corto (por ejemplo, 1 minuto) para volver a enmascarar automáticamente los detalles llamando a `maskCardDetails` y reducir la exposición.
{% endhint %}

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

```kotlin
fun showCardDetails(cardDetailsUI: CardDetailsUI, activity: FragmentActivity) {
        activity.lifecycleScope.launch {
            try {
                // Enmascare los detalles de la tarjeta
                cardDetailsUI.maskCardDetails()

                // Muestra los detalles de la tarjeta de nuevo
                cardDetailsUI.showCardDetails().await()
                // La interfaz de usuario se actualiza
            } catch (exception: D1Exception) {
                // Consulte la sección Integración del SDK D1 – Gestión de errores
            }
    }
}
```

{% endtab %}

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

```kotlin
fun showCardDetails (cardDetailsUI: CardDetailsUI) {
  // Enmascara los detalles de la tarjeta.
  cardDetailsUI.maskCardDetails()

  val callback = object : D1Task.Callback<Void> {
    override fun onSuccess(ignore: Void?) {
      // La interfaz de usuario se actualiza.
    }

    override fun onError(exception: D1Exception) {
      // Consulte la sección Integración del SDK D1 – Gestión de errores.
    }
  }

  // Muestra los detalles de la tarjeta de nuevo.
  cardDetailsUI.showCardDetails(callback)
}
```

{% endtab %}

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

```swift
// enmascara los detalles de la tarjeta
cardDetailsUI.maskCardDetails()

// muestra los detalles de la tarjeta de nuevo
do {
    try await cardDetailsUI.showCardDetails()
    // Continúe con los flujos posteriores
} catch let d1Error as D1Error {
    // Consulte la sección Integración del SDK D1 – Gestión de errores
} catch let error {
    // Manejar otro error
}
```

{% endtab %}

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

<pre class="language-swift"><code class="lang-swift"><strong>// enmascara los detalles de la tarjeta
</strong>cardDetailsUI.maskCardDetails()

// muestra los detalles de la tarjeta de nuevo
cardDetailsUI.showCardDetails() { error in
    if let error = error {
        // Consulte la sección Integración del SDK D1 – Gestión de errores
    } else {
        // La interfaz de usuario se actualiza
    }
}
</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/es/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.
