> 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/es/integracion-del-sdk/ios-api/migrate-from-2.x-to-3.0.md).

# Migrar de 2.x a 3.0

A partir de TMG SDK 3.0.0, varias API públicas se simplifican.

## Inicializar el SDK <a href="#initialisation-of-sdk" id="initialisation-of-sdk"></a>

El SDK elimina `TMGClientConfiguration.Builder` y mueve la configuración al `TMGClientConfiguration` inicializador:

* Eliminado: [`TMGClientConfiguration.Builder`](https://thalesgroup.github.io/d1sdk-docs/tmg-sdk/ios/2.1.0/Classes/TMGClientConfiguration/Builder.html)
* Usar en su lugar: [`TMGClientConfiguration`](https://thalesgroup.github.io/d1sdk-docs/tmg-sdk/ios/3.0.0/Classes/TMGClientConfiguration.html)

### Qué cambió

* Obsoleto `certificatePins`. El SDK ahora gestiona el pinning de certificados internamente.
* Renombrado `serverUrl` a `serverURL`.
* Renombrado `serverKeyId` a `serverKeyID`.

{% tabs %}
{% tab title="Antes de 3.0.0" %}

```swift
let serverUrl;
let serverCertificate;
let keyIdentifier;
let configurationBuilder = TMGClientConfiguration.Builder(serverUrl: serverUrl, 
                                                          serverCertificate: Data(serverCertificate.utf8), 
                                                          serverKeyId: keyIdentifier)
let configuration: TMGClientConfiguration = TMGClientConfiguration(builder: configurationBuilder)
```

{% endtab %}

{% tab title="3.0.0" %}

```swift
let serverURL = ""
let serverCertificate = ""
let serverKeyID = ""
let configuration = TMGClientConfiguration(serverURL: serverURL,
                                           serverCertificate: Data(serverCertificate.utf8),
                                           serverKeyID: serverKeyID)
```

{% endtab %}
{% endtabs %}

### Inicializar `VisaCTFHelper` <a href="#initialisation-of-visactfhelper" id="initialisation-of-visactfhelper"></a>

En TMG SDK 3.0.0, `createVisaCTFHelper` cambia de asíncrono a síncrono. Esto simplifica el manejo de errores y el flujo de control.

{% tabs %}
{% tab title="Antes de 3.0.0" %}

```swift
let tmgClient = TMGClient.sharedInstance
tmgClient.createVisaCTFHelper(tmgClientConfiguration: configuration,
                              completion: { (visaCTFHelper, error) in
  // Obtiene el objeto VisaCTFHelper
  // Verifica el error
})
```

{% endtab %}

{% tab title="3.0.0" %}

```swift
do {
    let visaCTFHelper = try TMGClient.sharedInstance.createVisaCTFHelper(withConfiguration: configuration)
} catch let error {
    // Manejar el error
}
```

{% endtab %}
{% endtabs %}

### Actualizar los flujos de vinculación de dispositivo (verde y amarillo) <a href="#device-binding-in-green-and-yellow-flow" id="device-binding-in-green-and-yellow-flow"></a>

La vinculación de dispositivo abarca la autenticación del dispositivo, Identificación y Verificación (ID\&V), y la finalización de la vinculación. En TMG SDK 3.0.0, el flujo:

* Estandarizó el uso de `completionHandler`.
* Eliminó la mezcla de `delegate` y `completionHandler`.
* Eliminó la necesidad de manejar el éxito de la vinculación en múltiples lugares.
* Optimizado el flujo de control.

{% hint style="info" %}
Al migrar desde versiones anteriores del SDK, tenga en cuenta estos cambios de nombre en la API:

* `PendingBindingSession` ahora es `VisaCTFHelper.IDVSession`.
* `DeviceAuthenticationDelegate` ahora es `DeviceAuthentication`.
* `IdvMethod` ahora es `IDVMethod`.
* `IdvType` ahora es `IDVType`.
* `OtpActivationStatus` ahora es `OTPActivationStatus`.
  * `maxOtpRequestsAllowed` ahora es `maxOTPRequestsAllowed`.
  * `maxOtpVerificationAllowed` ahora es `maxOTPVerificationAllowed`.
    {% endhint %}

Use el código a continuación para actualizar su integración de vinculación de dispositivo:

{% tabs %}
{% tab title="Antes de 3.0.0" %}

```swift
// 1. conforme al DeviceAuthenticationDelegate (esto es para la autenticación del dispositivo)
class DeviceAuthenticationDelegateImplementation: DeviceAuthenticationDelegate {

    let authenticationMessage

    func shouldStartAuthentication(startHandler: (String?, Bool) -> Void) {
        //3. Iniciar la autenticación del usuario 
        startHandler(authenticationMessage, YES)
    }
}

var pendingBindingSession: PendingBindingSession?
let deviceId
let correlationId
let deviceAuthenticationDelegate = DeviceAuthenticationDelegateImplementation()
// 2. Iniciar crear vinculación
visaCTFHelper.createBinding(vProvisionedTokenId: vProvisionedTokenId,
                            correlationId: correlationId,
                            deviceAuthenticationDelegate: deviceAuthenticationDelegate) { session, error in
    // 4. Éxito al vincular [Escenario 1]
    if error == nil && session == nil {

    }
    // 5. Almacenar localmente la sesión para el flujo amarillo
    pendingBindingSession = session
}
// MARK: flujo idv
// 6. Obtener lista de métodos idv (flujo Amarillo)
pendingBindingSession.idvMethods(completion: { idvMethods, error in
    if error == nil {
        let listOfIdvMethod = idvMethods
    }
})

//7. Enviar el método idv seleccionado (flujo OTP)
let selectedIdvMethod
pendingBindingSession.submitIdvMethod(idvMethod: selectedIdvMethod,
                                      completion: { otpActivationStatus, error in
     // Verificar que no haya error
    if error == nil {
        let maxOtpVerificationAllowed = otpActivationStatus.maxOtpRequestsAllowed
        let maxOtpRequestsAllowed = otpActivationStatus.maxOtpVerificationAllowed
        let otpExpiration = otpActivationStatus.maxOtpVerificationAllowed
    }
    // 8. reintentar si hay error
    
})

//9. Activar vinculación
let otp
pendingBindingSession.activateBinding(otp: otp, 
                                      completion: { error in
    // 4.1 Éxito al vincular [Escenario 2]
    if error == nil {

    }
    // 10. Reintentar si hay error
})
```

{% endtab %}

{% tab title="3.0.0" %}

```swift
// La clase singleton para mantener las propiedades requeridas para el flujo de visa
class VisaService {
    static var shared = VisaService()
    var idvSession: VisaCTFHelper.IDVSession? = nil
    var completionHandler: ((VisaCTFHelper.IDVSession?, TMGError?) -> Void)? = nil
}

let vProvisionedTokenID: String = ""
let correlationID: String = ""
// 1. Iniciar crear vinculación
visaCTFHelper.createBinding(forVProvisionedTokenID: vProvisionedTokenID,
                            correlationID: correlationID,
    deviceAuthenticationHandler: { auth in
        // 2. Iniciar la autenticación del usuario
        let customMessage = "" // Pasar el mensaje personalizado. p.ej.: "Autentíquese con Face ID"
        auth.startAuthentication(withMessage: customMessage)
    }, idvSessionHandler: { session in
        // 3. Almacenar localmente la sesión para el flujo amarillo
        VisaService.shared.idvSession = session

    }, completionHandler: { session, error in
        // 4. mantener el manejador de finalización localmente
        VisaService.shared.completionHandler?(session, error)
    })

// MARK: flujo idv
do {
    guard let session = VisaService.shared.idvSession else {
        return
    }
    // 5. Obtener lista de métodos idv (flujo Amarillo)
    let idvMethods = try session.idvMethods
    // 6. Enviar el método idv seleccionado (flujo OTP)
    session.selectIDVMethod(idvMethods[0]) { otp in
        // Verificar estado de activación OTP
    }
} catch let error {
    // error en la lista de métodos idv
}

// 7. Activar Vinculación
let otp = ""
VisaService.shared.idvSession?.activateBinding(withValue: otp)

// 8. Manejar éxito o error.
// Puede escuchar completionHandler para éxito o error
VisaService.shared.completionHandler = {(session, error) in
    // 9. Éxito al vincular
    if error == nil {
        
    } else if let error, let session {
        // 10. Reintentar si hay error
        if error.description == TMGError.invalidOTPMessage.description {
            VisaService.shared.idvSession = session
        }
    } else {
        // 11. Manejar error
    }
}
```

{% endtab %}
{% endtabs %}

### Reanudar una vinculación (`resumeBinding`) <a href="#resumebinding-api" id="resumebinding-api"></a>

El `resumeBinding` flujo no cambia respecto a versiones anteriores. Solo los `IDVSession` pasos de (ID\&V) cambian.

{% tabs %}
{% tab title="Antes de 3.0.0" %}

```swift
var pendingBindingSession: PendingBindingSession?
// 1. Iniciar reanudar vinculación
visaCTFHelper.resumeBinding(vProvisionedTokenId: vProvisionedTokenId) { session, error in
    // 2. Almacenar localmente la sesión para el flujo amarillo
    if error == nil { 
        pendingBindingSession = session
    }
    // Verificar error
}

// 3. MARK: flujo idv (consulte el flujo idv de crear vinculación en el fragmento de código)
```

{% endtab %}

{% tab title="3.0.0" %}

```swift
// La clase singleton para mantener las propiedades requeridas para el flujo de visa
class VisaService {
    static var shared = VisaService()
    var idvSession: VisaCTFHelper.IDVSession? = nil
    var completionHandler: ((VisaCTFHelper.IDVSession?, TMGError?) -> Void)? = nil
}
let vProvisionedTokenID: String = ""
// 1. Iniciar reanudar vinculación
visaCTFHelper.resumeBinding(forVProvisionedTokenID: vProvisionedTokenID,
                            idvSessionHandler: { session in
        // 2. Almacenar localmente la sesión para el flujo amarillo
        VisaService.shared.idvSession = session        
    }, completionHandler: { session, error in
        // 3. mantener el manejador de finalización localmente
        VisaService.shared.completionHandler?(session, error)
    })
// 4. MARK: flujo idv (consulte el flujo idv de crear vinculación en el fragmento de código)
```

{% endtab %}
{% endtabs %}

### Obtener el estado de la vinculación (`bindingState`) <a href="#bindingstate-api" id="bindingstate-api"></a>

En TMG SDK 3.0.0, `bindingState` cambia de asíncrono a síncrono. Esto simplifica el manejo de errores y el flujo de control.

{% tabs %}
{% tab title="Antes de 3.0.0" %}

```swift
let vProvisionedTokenId = ""
visaCTFHelper.bindingState(vProvisionedTokenId: vProvisionedTokenId) { (bindingState, error) in 
}
```

{% endtab %}

{% tab title="3.0.0" %}

```swift
let vProvisionedTokenID = ""
do {
    let state = try visaCTFHelper.bindingState(forVProvisionedTokenID: vProvisionedTokenID)
} catch let error {
    // Manejar el error
}
```

{% endtab %}
{% endtabs %}

### Autenticar una transacción <a href="#transaction-flow" id="transaction-flow"></a>

La autenticación de transacciones cubre la autenticación del dispositivo y la devolución de la carga útil de Visa. En TMG SDK 3.0.0, el flujo:

* Estandarizó el uso de `completionHandler`.
* Eliminó la mezcla de `delegate` y `completionHandler`.

Use el código a continuación para actualizar su integración de autenticación de transacciones:

{% tabs %}
{% tab title="Antes de 3.0.0" %}

```swift
// 1. conforme al DeviceAuthenticationDelegate (esto es para la autenticación del dispositivo)
class DeviceAuthenticationDelegateImplementation: DeviceAuthenticationDelegate {

    let authenticationMessage

    func shouldStartAuthentication(startHandler: (String?, Bool) -> Void) {
        //3. Iniciar la autenticación del usuario 
        startHandler(authenticationMessage, YES)
    }
}

let deviceAuthenticationDelegate = DeviceAuthenticationDelegateImplementation()

// 2. Iniciar autenticación de transacción
visaCTFHelper.authenticateTransaction(vProvisionedTokenId: vProvisionedTokenID,
                                      deviceAuthenticationDelegate: deviceAuthenticationDelegate,
                                      completion: { visaPayload, error in
    // 4. Generar la carga útil con éxito
    if error == nil {
    
    } else {
        // Manejar error
    } 
})
```

{% endtab %}

{% tab title="3.0.0" %}

```swift
let vProvisionedTokenID: String = ""
        
// 1. Iniciar autenticación de transacción
visaCTFHelper.authenticateTransaction(forVProvisionedTokenID: vProvisionedTokenID,
                                        deviceAuthenticationHandler: { auth in
        // 2. Iniciar la autenticación del usuario 
        let customMessage = "" // Pasar el mensaje personalizado. p.ej.: "Autentíquese con Face ID"
        auth.startAuthentication(withMessage: customMessage)
    }, completionHandler: { (visaPayload, error) in
        // 3. Éxito al generar la carga útil
        if error == nil {
            
        } else {
            // Manejar error
        }    
})
```

{% endtab %}
{% endtabs %}

### Eliminar una vinculación (`removeBinding`) <a href="#removebinding-api" id="removebinding-api"></a>

`removeBinding` ahora requiere un `correlationID`.

{% tabs %}
{% tab title="Antes de 3.0.0" %}

```swift
// 1. Iniciar eliminar vinculación
visaCTFHelper.removeBinding(vProvisionedTokenId: vProvisionedTokenID,
                            completion: { error in
    // 2. Éxito al eliminar vinculación
    if error == nil {
        
    } else {
        // Manejar error
    }
})
```

{% endtab %}

{% tab title="3.0.0" %}

```swift
let vProvisionedTokenID: String = ""
let correlationID: String = ""

// 1. Iniciar eliminar vinculación
visaCTFHelper.removeBinding(forVProvisionedTokenID: vProvisionedTokenID,
                            correlationID: correlationID) { error in
    // 2. Éxito al eliminar vinculación
    if error == nil {
        
    } else {
        // Manejar error
    } 
}
```

{% endtab %}
{% endtabs %}

### Sincronizar estado de vinculación (`syncBindingState`) <a href="#syncbindingstate-api" id="syncbindingstate-api"></a>

`syncBindingState` ahora requiere un `correlationID`.

{% tabs %}
{% tab title="Antes de 3.0.0" %}

```swift
// 1. Iniciar sincronización del estado de vinculación
visaCTFHelper.syncBindingState(vProvisionedTokenId: vProvisionedTokenID,
                               completion: { bindingState, error in
    // 2. Éxito al sincronizar el estado de vinculación
    if error == nil {
        
    } else {
        // Manejar error
    }  
})
```

{% endtab %}

{% tab title="3.0.0" %}

```swift
let vProvisionedTokenID: String = ""
let correlationID: String = ""

// 1. Iniciar sincronización del estado de vinculación
visaCTFHelper.syncBindingState(forVProvisionedTokenID: vProvisionedTokenID,
                                correlationID: correlationID) { (state, error) in
    // 2. Éxito al sincronizar el estado de vinculación
    if error == nil {
        
    } else {
        // Manejar error
    }   
}
```

{% endtab %}
{% endtabs %}

### Leer el método ID\&V previamente seleccionado <a href="#previouslyselectedidvmethod-in-idvsession" id="previouslyselectedidvmethod-in-idvsession"></a>

Además de las `IDVSession` funciones utilizadas en el `createBinding` flujo, puede leer el método ID\&V previamente seleccionado. En TMG SDK 3.0.0, `previouslySelectedIDVMethod` cambia de asíncrono a síncrono. Esto simplifica el manejo de errores y el flujo de control.

{% tabs %}
{% tab title="Antes de 3.0.0" %}

```swift
// 1. Obtener el método idv previamente seleccionado
pendingBindingSession.previouslySelectedIdvMethod(completion: { idvMethod, error in
    // 2. obtener con éxito el método idv previamente seleccionado
    if error == nil {
        let prevIDVMethod = idvMethod
    } else {
        // Manejar error
    } 
})
```

{% endtab %}

{% tab title="3.0.0" %}

```swift
guard let idvSession = VisaService.shared.idvSession else {
    // no hay sesión idv
    return
}
// 1. Obtener el método idv previamente seleccionado
do {
    let prevIDVMethod = try idvSession.previouslySelectedIDVMethod
} catch let error {
    // 2. manejar 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/es/integracion-del-sdk/ios-api/migrate-from-2.x-to-3.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.
