> 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-yellow-flow/activate-binding-with-otp.md).

# Activate binding with OTP

One-time Password (OTP) is used as the **ID\&V** method to activate a pending device binding.

This page continues the flow after [Create device binding (yellow flow)](/merchant-tokenization/visa-ctf-and-daf/implement-ctf-and-daf/create-device-binding-yellow-flow.md).

Prerequisites:

* You already started `createBinding` or `resumeBinding`.
* The issuer selected an OTP-based ID\&V method (for example, `OTP_SMS`).
* Your merchant application can collect an OTP from the end user.

## Flow

<figure><img src="/files/BrVOIXH5CYojXqUaNN4F" alt=""><figcaption><p>OTP device binding flow.</p></figcaption></figure>

<table><thead><tr><th width="100">Step</th><th>Description</th></tr></thead><tbody><tr><td>1</td><td>The end user selects an OTP option (SMS, email or online banking).</td></tr><tr><td>2</td><td>The merchant application forwards the selection to the Thales backend.</td></tr><tr><td>3–5</td><td>Thales backend requests <strong>VTS</strong> and the <strong>issuer</strong> to deliver the OTP over the selected channel.</td></tr><tr><td>6</td><td>The end user enters the OTP in the merchant application. The merchant application owns the UI.</td></tr><tr><td>7–8</td><td>Thales backend validates the OTP with VTS and the issuer.</td></tr><tr><td>9</td><td>Thales SDK receives the result and activates the binding locally.</td></tr><tr><td>10</td><td>Thales backend notifies the merchant/PSP backend that the binding is active.</td></tr></tbody></table>

## SDK integration

### 1. Select an OTP ID\&V method

During `createBinding` or `resumeBinding`, select one of the OTP ID\&V methods:

* `OTP_SMS`
* `OTP_EMAIL`
* `OTP_ONLINE_BANKING`

{% tabs %}
{% tab title="Android" %}
Once the application submits the selected `ID&V` method successfully, the `onIssuerAuthenticationReady` callback will be returned to the application. Otherwise, an `onError` callback will be returned.

```java
@Override
public void onIssuerAuthenticationRequired(PendingBindingSession pendingBindingSession) { 
    // Submit OTP_SMS ID&V Method
    for (IDVMethod idvMethod : pendingBindingSession.getIdvMethods()) {
        if (idvMethod.getType().equals(IDVType.OTP_SMS)) {
            pendingBindingSession.submitIdvMethod(idvMethod);
        }
    }
}

@Override
public void onIssuerAuthenticationReady(PendingBindingSession pendingBindingSession, 
                                        @Nullable OtpActivationStatus status) {
    
}

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

{% endtab %}

{% tab title="iOS" %}

```swift
guard let idvSession = VisaService.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 an OTP idv method (OTP_SMS)
    
    // 2. submit the idv method
    idvSession.selectIDVMethod(selectedIdvMethod) { (result) in
        if let otpActivationStatus = result {
            let maxOtpVerificationAllowed = otpActivationStatus.maxOTPVerificationAllowed
            let maxOtpRequestsAllowed = otpActivationStatus.maxOTPRequestsAllowed
            let otpExpiration = otpActivationStatus.otpExpiration
            
            // 3. Display page to enter OTP
        }
    }
} catch let error {
    // handle error
}

// 4. Failure in step 2, selectIDVMethod, will be handled in completionHandler.
VisaService.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 {
        VisaService.shared.idvSession = session
        // 6. Retry the IDV flow.
    }
}
```

{% endtab %}
{% endtabs %}

### 2. Activate the binding

Collect the OTP in your merchant application, then call `activateBinding` on the `IDVSession`.

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

```java
@Override
public void onIssuerAuthenticationReady(IDVSession idvSession, 
                                        @Nullable OtpActivationStatus status) { 
    // Activate binding
    String otp;
    idvSession.activateBinding(otp);
}

@Override
public void onIssuerAuthenticationError(@Nullable IDVSession idvSession, 
                                        TMGClientException tmgClientException) {
    // Check the error or retry
}
```

The result is returned via `onSuccess` or `onIssuerAuthenticationError`.

If activation fails, use the `IDVSession` returned in `onIssuerAuthenticationError` to retry.
{% endtab %}

{% tab title="iOS" %}

```swift
// 1. OTP value from user input
let otp = ""

guard let idvSession = VisaService.shared.idvSession else {
    // no idv session
    return
}
// 2. Call activate
idvSession.activateBinding(withValue: otp)

VisaService.shared.completionHandler = { (session, error) in
    // 2. Binding successful
    if error == nil {
        
    } else if let error = error,
                let session = session,
                error.description == TMGError.serverErrorWrongOTP.description {
        VisaService.shared.idvSession = session
        // 3. Retry OTP input and display error message
    }
}
```

The result is returned in `completionHandler`.

If activation fails, `completionHandler` returns an `IDVSession` and an error for retry.
{% 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:

```
GET https://docs.payments.thalescloud.io/merchant-tokenization/visa-ctf-and-daf/implement-ctf-and-daf/create-device-binding-yellow-flow/activate-binding-with-otp.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
