> 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/release-notes/sdk/june-2026/d1-sdk-v4.4.0/asynchronous-apis-on-d1-sdk-4.4.0.md).

# Asynchronous APIs on D1 SDK 4.4.0

## Asynchronous APIs on D1 SDK 4.4.0

#### Overview

D1 SDK 4.4.0 introduces asynchronous API updates for Android and iOS.

On Android, the updated APIs support coroutine-based integrations. On iOS, the updated APIs support Swift concurrency. These changes apply to the Secure Card Display and Push Provisioning APIs.

Use this guide to review the affected APIs and update your issuer application.

#### What changed

The previous API surface is deprecated in D1 SDK 4.4.0. The deprecated APIs are now provided under the relevant product:

* Use Secure Card Display for card display flows.
* Use Push Provisioning for wallet digitization flows.

If your issuer application uses asynchronous calls, update those calls during the migration:

* On Android, use the Kotlin coroutine-based APIs.
* On iOS, use the Swift concurrency-based APIs.

This page lists the APIs changed in 4.4.0.

#### Migrate to the product-specific APIs

{% stepper %}
{% step %}

#### Review your current integration

Identify the deprecated D1 SDK APIs used by your issuer application.

Focus on the APIs used for Secure Card Display and Push Provisioning flows.
{% endstep %}

{% step %}

#### Move to the product-specific APIs

* Replace each deprecated API with the corresponding product-specific API.&#x20;
* Use Secure Card Display APIs for card display features.
* Use Push Provisioning APIs for wallet digitization features.
  {% endstep %}

{% step %}

#### Update asynchronous calls

* On Android, replace existing asynchronous calls with the Kotlin coroutine-based APIs.
* On iOS, replace existing asynchronous calls with the Swift concurrency APIs.
  {% endstep %}

{% step %}

#### Validate the migrated flows

* Build and test your issuer application after the migration.
* Validate Secure Card Display and Push Provisioning flows.
  {% endstep %}
  {% endstepper %}

#### Update asynchronous handling

{% tabs %}
{% tab title="Android" %}
Use the Kotlin coroutine-based APIs if your issuer application uses Kotlin coroutines.

This simplifies asynchronous code and reduces callback handling.

Secure Card Display and Push Provisioning calls now return `Task<T>` instead of using `Callback`.

**Use `await()` in coroutine-based integrations**

Import the `await` extension explicitly:

```kotlin
import com.thalesgroup.gemalto.d1.await
```

Coroutine-based example:

```kotlin
fun getCardMetaData(d1Task: D1Task, cardID: String, activity: FragmentActivity) {
   activity.lifecycleScope.launch {
       try {
           val cardMetadata = d1Task.secureCardDisplayService.getCardMetadata(cardID).await()

           // Last 4 digits of PAN
           val last4Pan = cardMetadata.last4Pan

           // CardAsset is used to display Card Artwork
           val cardAssets = cardMetadata.getAssetList().await()
           // Proceeds with the application logic
       } catch (exception: D1Exception) {
           // Refer to D1 SDK Integration – Error Management section
       }
   }
}
```

**Use `execute(callback)` in non-coroutine integrations**

```kotlin
public void getCardMetaData(@NonNull D1Task d1Task, @NonNull String cardID) {
   D1Task.Callback<CardMetadata> callback = new D1Task.Callback<CardMetadata>() {
       @Override
       public void onSuccess(CardMetadata cardMetadata) {
           // Last 4 digits of PAN
           String last4Pan = cardMetadata.getLast4Pan();

           // Note: Asset list retrieval is handled separately in getAssetList() method
           // Proceeds with the application logic
       }

       @Override
       public void onError(D1Exception exception) {
           // Refer to D1 SDK Integration – Error Management section
       }
   };

   d1Task.getSecureCardDisplayService().getCardMetadata(cardID).execute(callback);
}
```

{% endtab %}

{% tab title="iOS" %}
Use the Swift concurrency APIs if your issuer application uses Swift concurrency.

This makes asynchronous code easier to read and maintain.

Secure Card Display and Push Provisioning calls now use `async throws` instead of completion handlers.
{% endtab %}
{% endtabs %}

#### API changes in 4.4.0

Use this section to review the APIs changed in D1 SDK 4.4.0.

Initialize each product service from `d1Task` before calling the product APIs.

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

```kotlin
val pushProvisioningService = d1Task.pushProvisioningService
val secureCardDisplayService = d1Task.secureCardDisplayService
```

{% endtab %}

{% tab title="iOS" %}

```swift
let secureCardDisplayService = try d1Task.secureCardDisplayService()
let pushProvisioningService = try d1Task.pushProvisioningService()
```

{% endtab %}
{% endtabs %}

**Secure Card Display**

{% tabs %}
{% tab title="Android" %}
**`getCardMetadata`**

Before:

```java
getCardMetadata(String cardID, Callback<CardMetadata> callback)
```

Now:

```java
Task<CardMetadata> getCardMetadata(String cardID)
```

**`getCardDetails`**

Before:

```java
getCardDetails(String cardID, Callback<CardDetails> callback)
```

Now:

```java
Task<CardDetails> getCardDetails(String cardID)
```

**`displayCardDetails`**

Before:

```java
displayCardDetails(String cardID, CardDetailsUI cardDetailsUI, Callback<Void> callback)
```

Now:

```java
Task<Void> displayCardDetails(String cardID, CardDetailsUI cardDetailsUI)
```

{% endtab %}

{% tab title="iOS" %}
**`cardMetadata`**

Before:

```swift
cardMetadata(_ cardID: String, completion: @escaping (CardMetadata?, D1Error?) -> Void)
```

Now:

```swift
cardMetadata(_ cardID: String) async throws -> CardMetadata
```

**`cardDetails`**

Before:

```swift
cardDetails(_ cardID: String, completion: @escaping (CardDetails?, D1Error?) -> Void)
```

Now:

```swift
cardDetails(_ cardID: String) async throws -> CardDetails
```

**`displayCardDetails`**

Before:

```swift
displayCardDetails(_ cardID: String, cardDetailsUI ui: CardDetailsUI, completion: @escaping (D1Error?) -> Void)
```

Now:

```swift
displayCardDetails(_ cardID: String, cardDetailsUI: CardDetailsUI) async throws
```

{% endtab %}
{% endtabs %}

**Push Provisioning**

{% tabs %}
{% tab title="Android" %}
**`addDigitalCardToScheme`**

Before:

```java
addDigitalCardToScheme(String cardID, TokenRequestor tokenRequestor, String appURL, boolean tcsAccepted, Callback<String> callback)
```

Now:

```java
Task<String> addDigitalCardToScheme(String cardID, TokenRequestor tokenRequestor, String appURL, boolean tcsAccepted)
```

**`addDigitalCardToOEM`**

Before:

```java
addDigitalCardToOEM(String cardID, OEMPayType oemType, Activity activity, D1Task.Callback<Object> callback)
```

Now:

```java
Task<Object> addDigitalCardToOEM(String cardID, OEMPayType oemType, Activity activity, int options)
```

**`getTokenRequestorList`**

Before:

```java
getTokenRequestorList(String cardID, Callback<List<TokenRequestor>> callback)
```

Now:

```java
Task<List<TokenRequestor>> getTokenRequestorList(String cardID)
```

**`getCardDigitizationState`**

Before:

```java
getCardDigitizationState(String cardID, OEMPayType oemType, D1Task.Callback<CardDigitizationState> callback)
```

Now:

```java
Task<CardDigitizationState> getCardDigitizationState(String cardID, OEMPayType oemType)
```

New in 4.4.0:

```java
Task<CardDigitizationState> getCardDigitizationState(OEMPayType oemType, String last4)
```

{% endtab %}

{% tab title="iOS" %}
**`cardDigitizationState`**

Before:

```swift
cardDigitizationState(_ cardID: String, completion: @escaping (CardDigitizationResult?, D1Error?) -> Void)
```

Now:

```swift
cardDigitizationState(_ cardID: String) async throws -> CardDigitizationResult
```

**`addDigitalCardToOEM`**

Before:

```swift
addDigitalCardToOEM(_ cardID: String, viewController: UIViewController, completion: @escaping (D1Error?) -> Void)
```

Now:

```swift
addDigitalCardToOEM(_ cardID: String, viewController: UIViewController) async throws
```

**`digitalCardPass` to `digitalCard`**

Before:

```swift
digitalCardPass(forSerialNumber serialNumber: String) throws -> PKPass?
```

Now:

```swift
digitalCard(forSerialNumber serialNumber: String) throws -> PKPass?
```

**`tokenRequestorList`**

Before:

```swift
tokenRequestorList(_ cardID: String, completion: @escaping ([TokenRequestor]?, D1Error?) -> Void)
```

Now:

```swift
tokenRequestorList(_ cardID: String) async throws -> [TokenRequestor]
```

**`addDigitalCardToScheme`**

Before:

```swift
addDigitalCardToScheme(_ cardID: String, tokenRequestor: TokenRequestor, appURL: String, termsAndConditionsAccepted: Bool, completion: @escaping (String?, D1Error?) -> Void)
```

Now:

```swift
addDigitalCardToScheme(_ cardID: String, tokenRequestor: TokenRequestor, appURL: String, termsAndConditionsAccepted: Bool) async throws -> String
```

New in 4.4.0:

```swift
cardDigitizationState(withLast4 last4: String) async throws -> CardDigitizationResult
```

{% 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/release-notes/sdk/june-2026/d1-sdk-v4.4.0/asynchronous-apis-on-d1-sdk-4.4.0.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.
