> 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/visa-ctf-and-daf/implement-ctf-and-daf/create-device-binding-green-flow.md).

# Create device binding (green flow)

Use the Visa Cloud Token Framework (CTF) device binding **green flow** when the issuer approves device binding **without** step-up authentication.

{% hint style="info" %}
In Production, device binding often requires step-up authentication. That path is the **yellow flow**.
{% endhint %}

Prerequisites:

* The payment card is already tokenized.
* You have a `vProvisionedTokenId`.
* The end user can authenticate on the device (PIN, passcode, fingerprint, Face ID, etc.).

## Flow

<figure><img src="/files/Vjng3UHslvqwCmE6Q5EW" alt=""><figcaption><p>Device binding green flow.</p></figcaption></figure>

<table><thead><tr><th width="100">Step</th><th>Description</th></tr></thead><tbody><tr><td>1</td><td>Start the device binding flow from the merchant application using the Thales SDK.</td></tr><tr><td>2</td><td>Thales SDK generates a device ID and a CTF key pair, then store the CTF key pair securely on the device.</td></tr><tr><td>3</td><td>Thales SDK triggers the end user authentication on the device.</td></tr><tr><td>4</td><td>Thales SDK generates and signs the Visa-defined payload.</td></tr><tr><td>5</td><td>Thales SDK sends the signed payload and the CTF public key to the Thales backend.</td></tr><tr><td>6</td><td>Thales backend converts the public key into a certificate using a Visa CA.</td></tr><tr><td>7</td><td>Thales backend enrolls the device and request device binding to VTS.</td></tr><tr><td>8</td><td>VTS checks the issuer decision.</td></tr><tr><td>9</td><td>Issuer approves the device binding without step-up authentication.</td></tr><tr><td>10</td><td>VTS forwards the result to the Thales backend.</td></tr><tr><td>11</td><td>Thales SDK is informed and binds the token identifier locally to the device.</td></tr><tr><td>12</td><td>Thales backend notifies the merchant/PSP backend with the binding details.</td></tr></tbody></table>

## SDK integration

### Create a binding

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

```java
String vProvisionedTokenId;
String correlationId;

visaCTFHelper.createBinding(vProvisionTokenId, 
                            correlationId, 
                            new TokenBindingListener() {

        ......
        
        @Override
        public void onDeviceAuthentication(DeviceAuthentication deviceAuthentication) {
            // Do user authentication
         }

        @Override
        public void onSuccess() { }

        @Override
        public void onError(TMGClientException exception) { 
            // Check error
            int errorCode = exception.getErrorCode();
            int errorMessage = exception.getMessage();
        }
    });
```

{% endtab %}

{% tab title="iOS" %}

```swift
let vProvisionedTokenID: String = ""
let correlationID: String = ""
// 1. Start create binding
visaCTFHelper.createBinding(forVProvisionedTokenID: vProvisionedTokenID,
                            correlationID: correlationID,
    deviceAuthenticationHandler: { auth in
        // 2. faceID
        let customMessage = "" // Pass in the custom message. e.g: "Authenticate with Face ID"
        auth.startAuthentication(withMessage: customMessage)
    }, idvSessionHandler: { session in
        // Start idv session (only applicable for yellow flow)
        
    }, completionHandler: { session, error in
        // 3. binding successful
        if error == nil {
            
        }
        // Handle error or retry idv session when there is a failure (not applicable for green flow)
    })
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
`createBinding` is asynchronous. It is recommended to call `runOnUiThread(Runnable)` on the function callback in cases where the application has to update any UI.
{% endhint %}

### Authenticate the end user

Creating a device binding requires end user presence. Implement the `deviceAuhenticationHandler` callback from `createBinding`.

Use this callback to present any custom UI (for example, Face ID permission prompts). Start authentication by calling `startAuthentication`. You can also pass a custom message to display during authentication.

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

```java
@Override
public void onDeviceAuthentication(DeviceAuthentication deviceAuthentication) {
    FragmentActivity fragmentActivity;
    CharSequence title;
    CharSequence subTitle;
    CharSequence description;
    CharSequence negativeButtonText;

    // Start user authentication
    deviceAuthentication.startAuthentication(fragmentActivity, 
                                             title, 
                                             subTitle, 
                                             description, 
                                             negativeButtonText);
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
let deviceAuhenticationHandler: ((DeviceAuthentication) -> Void) = {(auth) in
    // Start user authentication
    let customMessage = "" // Pass in the custom message. e.g: "Authenticate with Face ID"
    auth.startAuthentication(withMessage: customMessage)
}
```

{% endtab %}
{% endtabs %}

#### Handle results

Results are returned via the `onSuccess` or `onError` callback.

On error, log and inspect the exception error code and message.

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

```java
@Override
public void onError(TMGClientException exception) {
    // Check the error
    int errorCode = exception.getErrorCode();
    int errorMessage = exception.getMessage();
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
let vProvisionedTokenID: String = ""
let correlationID: String = ""
// 1. Start create binding
visaCTFHelper.createBinding(forVProvisionedTokenID: vProvisionedTokenID,
                            correlationID: correlationID,
    deviceAuthenticationHandler: { auth in
        // 2. cancel device authentication
        auth.cancel()
    }, idvSessionHandler: { session in
        // Start idv session (only applicable for yellow flow)
        
    }, completionHandler: { session, error in
        if error == nil {
            
        }
        // 3. Handle the cancel error
    })
```

{% 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/visa-ctf-and-daf/implement-ctf-and-daf/create-device-binding-green-flow.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.
