> 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/nfc-wallet-sdk-android/implement-nfc-wallet/manage-digital-cards/display-digital-cards.md).

# Display digital cards

## Overview

After **Tokenization**, your **digital wallet application** should show the **end user** their digital cards.

Provide a list view and a details view.

Use card status, card art, and metadata to drive the UI.

## SDK integration

### Use `DigitalizedCardManager` <a href="#digitalizedcardmanager" id="digitalizedcardmanager"></a>

After **Tokenization** completes, use `DigitalizedCardManager` to access the **NFC Wallet SDK** persistent data and retrieve digital cards.

`DigitalizedCardManager` supports asynchronous and blocking calls:

* `AsyncHandler`: Receive results via callbacks.
* `AsyncToken`: Block the calling thread until the operation completes.

{% hint style="warning" %}
`AsyncToken` blocks the calling thread. Avoid it on the UI thread.
{% endhint %}

### Retrieve card list

After **Tokenization** completes, use `DigitalizedCardManager.getAllCards()` to retrieve all **tokenized card IDs**.

For the difference between identifiers, see [Tokenized card ID versus digital card ID](#tokenized-card-id-versus-digital-card-id).

The examples below show how to retrieve tokenized card IDs with `AsyncHandler` and `AsyncToken`.

{% tabs %}
{% tab title="AsyncHandler" %}
{% code title="Retrieve tokenized card IDs using AsyncHandler" %}

```kotlin
// Instantiate a HandlerThread to avoid work on the UI thread.
val cardDisplayThread = HandlerThread("getAllCards")
cardDisplayThread.start()

val looper = cardDisplayThread.looper

val handler = object : AbstractAsyncHandler<Array<String>>(looper) {
    override fun onComplete(result: AsyncResult<Array<String>>) {
        if (result.isSuccessful) {
            val tokenizedCardIds = result.result
            // TODO: display the cards
        } else {
            // TODO: handle error
        }
    }
}

DigitalizedCardManager.getAllCards(handler)
```

{% endcode %}
{% endtab %}

{% tab title="AsyncToken" %}
{% code title="Retrieve tokenized card IDs using AsyncToken" %}

```kotlin
val token = DigitalizedCardManager.getAllCards(null)
val result = token.waitToComplete()

if (result.isSuccessful) {
    val tokenizedCardIds = result.result
    // Display the cards in your UI
} else {
    // Handle error
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Tokenized card ID versus digital card ID <a href="#tokenized-card-id-versus-digital-card-id" id="tokenized-card-id-versus-digital-card-id"></a>

`DigitalizedCardManager` lists and retrieves cards using a **tokenized card ID**.

`DigitalizedCard.getTokenizedCardID()` returns the **tokenized card ID.**

This identifier is not the same as the **digital card ID**.

{% hint style="warning" %}
The **NFC Wallet SDK** uses two identifiers for the same card:

* **Tokenized card ID**: Generated during secure provisioning. Also known as a CPS token ID. See [Trigger provisioning](/nfc-wallet-sdk-android/implement-nfc-wallet/tokenize-a-card/trigger-provisioning.md).
* **Digital card ID**: Generated during digitization. Also known as an MG card ID. See [Digitize a card](/nfc-wallet-sdk-android/implement-nfc-wallet/tokenize-a-card/digitize-a-card.md).
  {% endhint %}

Use these helper methods to convert identifiers:

* `DigitalizedCardManager.getDigitalCardId()`: Get the digital card ID from a tokenized card ID.
* `DigitalizedCardManager.getTokenizedCardId()`: Get the tokenized card ID from a digital card ID.

{% hint style="info" %}
A TSP also provides its own digital card identifier.

Retrieve it in [Card metadata](#card-metadata).

Use it when troubleshooting with the TSP (VTS/MDES).

This identifier is different from the tokenized card ID and the digital card ID.
{% endhint %}

### Retrieve digital card information

#### Use `DigitalizedCard`

`DigitalizedCard` represents a digitized card and exposes card data, such as:

* `DigitalizedCardStatus`
  * Card state: `ACTIVE`, `SUSPENDED`
  * Payment keys status: Use it to detect replenishment needs.
* `DigitalizedCardDetails`
  * `getLastFourDigits()` : Last four digits of FPAN.
  * `getLastFourDigitsOfDPAN()` : Last four digits of DPAN.
  * `getPANExpiry()` : FPAN expiry date.
  * `getScheme()`: Payment network (Visa, Mastercard, and PURE).
* `DigitalizedCard.getPaymentAccountReference()`
  * Payment Account Reference (PAR) for the primary contactless card.

Retrieve a `DigitalizedCard` from `DigitalizedCardManager` using the **tokenized card ID**.

```kotlin
// Get the DigitalizedCard instance
val digitalizedCard = DigitalizedCardManager.getDigitalizedCard(tokenizedCardId)

// Get card state
val statusToken = digitalizedCard.getCardState(null)
val statusResult = statusToken.waitToComplete()

if (statusResult.isSuccessful) {
    val status = statusResult.result
    
    // Card states include ACTIVE and SUSPENDED
    // ACTIVE: Card can be used for payment
    // SUSPENDED: Card requires activation before payment
    val state = status.state
    
    // Payment key information
    val numberOfPaymentsLeft = status.numberOfPaymentsLeft
    val needsReplenishment = status.needsReplenishment()
    val expiryDate = status.expiryDate // LUK expiry date (null for SUK)
}

// Get card details
val detailsToken = digitalizedCard.getCardDetails(null)
val detailsResult = detailsToken.waitToComplete()

if (detailsResult.isSuccessful) {
    val details = detailsResult.result
    
    // Card metadata
    val lastFourDigits = details.lastFourDigits // Last four digits of FPAN
    val lastFourDigitsOfDPAN = details.lastFourDigitsOfDPAN // Last four digits of DPAN
    val panExpiry = details.panExpiry // FPAN expiry date
    val scheme = details.scheme // Payment network: Visa, Mastercard, PURE
}

// Get the PAR for the primary card
try {
    val paymentAccountReference = digitalizedCard.paymentAccountReference
    // Returns null if contactless data is unavailable or PAR is not present
} catch (e: InternalComponentException) {
    // Handle error
}
```

### Retrieve auxiliary card information

If the card is co-badged, you can retrieve additional properties from `DigitalizedCard`:

* `DigitalizedCard.hasAuxiliaryScheme()`: Returns `true` if the card has an auxiliary scheme.
* `DigitalizedCardDetails`
  * `getAuxiliaryLastFourDigitsOfDPAN()` : Last four digits of the auxiliary DPAN.
  * `getAuxiliaryScheme()` : Payment network for the auxiliary card.
* `DigitalizedCard.getAuxiliaryPaymentAccountReference()`: Payment Account Reference (PAR) for the auxiliary contactless card.

If the card is not co-badged, these properties return `null`.

```kotlin
// Check if the card has an auxiliary scheme
val hasAuxiliaryScheme = digitalizedCard.hasAuxiliaryScheme()

if (hasAuxiliaryScheme) {
    // Get auxiliary card details
    val detailsToken = digitalizedCard.getCardDetails(null)
    val detailsResult = detailsToken.waitToComplete()
    
    if (detailsResult.isSuccessful) {
        val details = detailsResult.result
        
        // Auxiliary scheme information
        val auxiliaryScheme = details.auxiliaryScheme // Auxiliary payment network
        val auxiliaryLastFourDigitsOfDPAN = details.auxiliaryLastFourDigitsOfDPAN // Last four digits of the auxiliary DPAN
    }
    
    // Get auxiliary payment key information
    val statusToken = digitalizedCard.getCardState(null)
    val statusResult = statusToken.waitToComplete()
    
    if (statusResult.isSuccessful) {
        val status = statusResult.result
        
        // Remaining payments for the auxiliary card
        val auxiliaryNumberOfPaymentsLeft = status.auxiliaryNumberOfPaymentsLeft
    }
    
    // Get the PAR for the auxiliary card
    try {
        val auxiliaryPaymentAccountReference = digitalizedCard.auxiliaryPaymentAccountReference
        // Returns null if:
        // - The card does not have an auxiliary scheme
        // - Contactless data is unavailable
        // - PAR is unavailable in contactless data
    } catch (e: InternalComponentException) {
        // Handle error
    }
}

// Note: If the card is not co-badged, auxiliary properties return null
```

#### Card metadata

Use `MGCardEnrollmentService.getCardMetaData()` and the **digital card ID** to retrieve card metadata, such as:

* TSP issuer name
* TSP ID (VTS, MDES, or another identifier)
* PAR (payment account reference)
* TSP digital card ID (`tokenId`)

For full field coverage, see the SDK API reference.

{% hint style="info" %}
TSP digital card ID (`tokenId`) maps to:

* Mastercard (MDES): `tokenUniqueReference`
* Visa (VTS): `tokenReferenceID`
  {% endhint %}

#### Card art

Use `MobileGatewayManager.getCardArt()` and the **digital card ID** to retrieve `CardArt`.

Use `CardArt.getBitmap()` to retrieve these images:

* `BANK_LOGO`: Issuer logo
* `CARD_BACKGROUND`: Card background
* `CARD_BACKGROUND_COMBINED`: Card background combined with the payment network
* `CARD_ICON`: Card icon

{% hint style="warning" %}
Card art retrieval triggers network requests; cache images within the digital wallet application to improve performance.
{% endhint %}

The sample application demonstrates a simple local caching approach:

{% code title="Cache card art locally" %}

```kotlin
fun getCardArt(context: Context, digitalCardId: String) {
    // First check if we already have the image locally
    val imageBytes = readFromFile(context, digitalCardId)
    if (imageBytes.isNotEmpty()) {
        val image = BitmapDrawable(
            context.resources,
            BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.size)
        )
        // Use the cached image in your UI
        return
    }

    // Download card art data from the backend
    val gatewayManager = MobileGatewayManager.INSTANCE
    try {
        val cardArt = gatewayManager.getCardArt(digitalCardId)
        cardArt.getBitmap(
            CardArtType.CARD_BACKGROUND_COMBINED,
            object : MGAbstractAsyncHandler<CardBitmap>() {
                override fun onComplete(result: MGAsyncResult<CardBitmap>) {
                    if (result.isSuccessful) {
                        val value = result.result
                        // Store data for future use
                        writeToFile(context, digitalCardId, value.resource)
                        val image = BitmapDrawable(
                            context.resources,
                            BitmapFactory.decodeByteArray(
                                value.resource,
                                0,
                                value.resource.size
                            )
                        )
                        // Use the downloaded image in your UI
                    }
                }
            }
        )
    } catch (exception: NoSuchCardException) {
        // Handle error - card not found
    }
}
```

{% endcode %}


---

# 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/nfc-wallet-sdk-android/implement-nfc-wallet/manage-digital-cards/display-digital-cards.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.
