> 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/merchant-tokenization/mastercard-taf/implement-taf/create-device-binding.md).

# Create device binding

Mastercard Token Authentication Framework (TAF) starts with device binding.

Prerequisites:

* The card has already completed tokenization. The merchant already has a `srcDigitalTokenId` from the Thales backend.
* The device supports device authentication, such as fingerprint or Face ID.

Before binding the token to the device, the issuer backend authenticates the end user (ID\&V). The issuer backend sends an OTP to the end user. The end user enters the OTP in the merchant application.

## The merchant application triggers the create binding flow

<figure><img src="/files/Roh23VZBZAhBtvlK0Ecw" alt=""><figcaption><p>Trigger a binding flow.</p></figcaption></figure>

<table><thead><tr><th width="100">Step</th><th>Description</th></tr></thead><tbody><tr><td>1-2</td><td>The end user (through the merchant application) triggers the ID&#x26;V flow by calling the Thales SDK with <code>tokenId</code> and a fresh <code>correlationId</code> (for troubleshooting).</td></tr><tr><td>3-7</td><td>The Thales SDK calls the Thales backend, which reaches Mastercard to retrieve the available ID&#x26;V methods.</td></tr><tr><td>8-9</td><td>The merchant application displays the available ID&#x26;V methods and asks the end user to select one. The options are SMS or email.</td></tr></tbody></table>

You can retrieve the list of ID\&V methods from the `IDVSession` object.

{% tabs %}
{% tab title="Android" %}
Use the `IDVSession` object to call `getIdvMethods` to get the list of supported `ID&V` methods.

```java
public void createBinding(@NonNull MastercardTAFHelper mastercardTAFHelper, @NonNull String tokenID, @NonNull String correlationID) {

    mastercardTAFHelper.createBinding(tokenID,
            correlationID,
            new TokenBindingListener() {

                @Override
                public void onIssuerAuthenticationReady(@NonNull IDVSession idvSession) {

                }

                @Override
                public void onIssuerAuthenticationRequired(IDVSession idvSession) {
                    // Get list of idv methods
                    List<IDVMethod> idvMethods = idvSession.getIdvMethods();
                }

                @Override
                public void onIssuerAuthenticationError(@NonNull IDVSession pendingBindingSession, TMGClientException tmgClientException) {
                    // Check the error or retry
                }

                @Override
                public void onDeviceAuthentication(DeviceAuthentication deviceAuthentication) {
                    // Perform device authentication using biometric
                }

                @Override
                public void onSuccess() {
                    // Handle UI of create binding success
                }

                @Override
                public void onError(TMGClientException exception) {
                    // Check if there's any error
                }
            });
}
```

{% endtab %}

{% tab title="iOS" %}
Use the `IDVSession` object to call `idvMethods` to get the list of supported `ID&V` methods.

```swift
// The singleton class to hold required properties for the Mastercard flow
class MastercardService {
    static var shared = MastercardService()
    var idvSession: MastercardTAFHelper.IDVSession? = nil
    var completionHandler: ((MastercardTAFHelper.IDVSession?, TMGError?) -> Void)? = nil
}

let tokenID: String = ""
let correlationID: String = ""
// Start create binding
mastercardTAFHelper.createBinding(forTokenID: tokenID, correlationID: correlationID, 
    idvSessionHandler: { idvSession in
        // hold the idv session locally
        MastercardService.shared.idvSession = idvSession
        // List of idv methods
        let methods = idvSession.idvMethods
        // Display idv methods to the user
    },
    deviceAuthenticationHandler: { auth in
        // faceID
        let customMessage = "" // Pass in the custom message. e.g: "Authenticate with Face ID"
        auth.startAuthentication(withMessage: customMessage)
    }, 
    completionHandler: { session, error in
        // hold the completion handler locally
        MastercardService.shared.completionHandler?(session, error)
        // binding successful
        if error == nil {
            
        }
        // Handle error or retry idv session when there is a failure
    }
)
```

{% endtab %}
{% endtabs %}

## End user selection and OTP sending <a href="#end-user-selection-and-otp-sending" id="end-user-selection-and-otp-sending"></a>

<figure><img src="/files/cuH1BTs4hMfUHb1ZCVPq" alt=""><figcaption><p>End user selects an ID&#x26;V method and receives the OTP.</p></figcaption></figure>

| Step | Description                                                                                                                                                                |
| ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1-2  | The end user selects an ID\&V method. The merchant application provides the selection to the Thales SDK.                                                                   |
| 3-7  | The Thales SDK calls the Thales backend, which reaches Mastercard, to generate an OTP. The issuer backend then sends the OTP to the end user through the selected channel. |

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

```java
public void selectIDVMethod(@NonNull MastercardTAFHelper mastercardTAFHelper, @NonNull String tokenID, @NonNull String correlationID, @NonNull FragmentActivity activity) {
    mastercardTAFHelper.createBinding(tokenID,
            correlationID,
            new TokenBindingListener() {

                @Override
                public void onIssuerAuthenticationReady(@NonNull IDVSession idvSession) {
                    // validate OTP
                }

                @Override
                public void onIssuerAuthenticationRequired(IDVSession idvSession) {
                    // Get list of idv methods
                    List<IDVMethod> idvMethods = idvSession.getIdvMethods();

                    // Submit selected idv method
                    IDVMethod selectedIdvMethod = idvMethods.get(0);
                    idvSession.selectIDVMethod(selectedIdvMethod);
                }

                @Override
                public void onIssuerAuthenticationError(@NonNull IDVSession pendingBindingSession, TMGClientException tmgClientException) {
                    // Check the error or retry
                }

                @Override
                public void onDeviceAuthentication(DeviceAuthentication deviceAuthentication) {
                    // Perform device authentication using biometric
                }

                @Override
                public void onSuccess() {
                    // Handle UI of create binding success
                }

                @Override
                public void onError(TMGClientException exception) {
                    // Check if there's any error
                }
            });
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
guard let idvSession = MastercardService.shared.idvSession else {
    // no idv session
    return
}
// 1. Display list of idv methods
do {
    let idvMethods = try idvSession.idvMethods
    let selectedIdvMethod = idvMethods[0] // user select 1 of the idvMethods available
    
    // 2. submit the idv method
    idvSession.selectIDVMethod(selectedIdvMethod) {
        // 3. display page to enter OTP value
    }
} catch let error {
    // handle error
}
        
// 4. Failure in step 2, selectIDVMethod, will be handled in completionHandler.
MastercardService.shared.completionHandler = { (session, error) in
    // 5. Check if it is a selectIDVMethod error.
    if let session = session,
        let error = error,
        error.description == TMGError.invalidIdvMethod.description {
        MastercardService.shared.idvSession = session
        // 6. Retry the IDV flow.
    }
}
```

{% endtab %}
{% endtabs %}

The SDK returns the binding activation result through `onSuccess` or `onIssuerAuthenticationError`. If activation fails, keep the `IDVSession` instance returned in `onIssuerAuthenticationError`. Use it to retry the ID\&V flow.

## OTP verification

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

<table><thead><tr><th width="100">Step</th><th>Description</th></tr></thead><tbody><tr><td>1-2</td><td>The end user enters the OTP in the merchant application, which sends it to the Thales SDK.</td></tr><tr><td>3-7</td><td>The SDK securely conveys the OTP to Mastercard for verification, then returns the result to the merchant application.</td></tr></tbody></table>

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

```java
public void validateOTP(@NonNull MastercardTAFHelper mastercardTAFHelper, @NonNull String tokenID, @NonNull String correlationID, @NonNull FragmentActivity activity) {
    mastercardTAFHelper.createBinding(tokenID,
            correlationID,
            new TokenBindingListener() {

                @Override
                public void onIssuerAuthenticationReady(@NonNull IDVSession idvSession) {
                    // Activate binding
                    String otp = "12345";
                    idvSession.validateOTP(otp);

                }

                @Override
                public void onIssuerAuthenticationRequired(IDVSession idvSession) {
                    // Get list of idv methods
                }

                @Override
                public void onIssuerAuthenticationError(@NonNull IDVSession pendingBindingSession, TMGClientException tmgClientException) {
                    // Check the error or retry
                }

                @Override
                public void onDeviceAuthentication(DeviceAuthentication deviceAuthentication) {
                    // Perform device authentication using biometric
                    CharSequence title = "title"; //title to be displayed in Biometric authentication popup.
                    CharSequence subTitle = "subTitle"; //subTitle to be displayed in Biometric authentication popup.
                    CharSequence description = "description"; // description to be displayed in Biometric authentication popup.
                    CharSequence negativeButtonText = "negativeButtonText"; // text of the negative button to be displayed in Biometric authentication popup.
                    deviceAuthentication.startAuthentication(activity,
                            title,
                            subTitle,
                            description,
                            negativeButtonText);
                }

                @Override
                public void onSuccess() {
                    // Handle UI of create binding success
                }

                @Override
                public void onError(TMGClientException exception) {
                    // Check if there's any error
                }
            });
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
guard let idvSession = MastercardService.shared.idvSession else {
    // no idv session
    return
}
do {
    let otp = "123456" // user entered OTP  value
    // 1. submit otp value
    idvSession.validateOTP(otp)
} catch let error {
    // handle error
}
        
// 2. Failure in step 1, validateOTP, will be handled in completionHandler.
MastercardService.shared.completionHandler = { (session, error) in
    // 3. Check if it is a validateOTP error.
    if let session = session,
        let error = error,
        error.description == TMGError.invalidOTPMessage.description {
        MastercardService.shared.idvSession = session
        // 4. Retry the IDV flow.
    }
}
```

{% 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/merchant-tokenization/mastercard-taf/implement-taf/create-device-binding.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.
