> For the complete documentation index, see [llms.txt](https://docs.payvalida.com/api-tarjeta/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.payvalida.com/api-tarjeta/master/sdk-para-3ds-y-score-de-riesgo-transaccional/guia-de-integracion-con-el-sdk-para-ios-swift/3.-ejemplo-de-uso-swift.md).

# 3. Ejemplo de Uso (Swift)

### Validación Antifraude

La validación antifraude es un proceso de dos pasos:

1. Debes llamar a <mark style="color:$success;">`startAntiFraudValidator`</mark> mientras el usuario escribe la información de su tarjeta (con un debounce). Esta verificación inicial te indicará si se requiere 3DS.&#x20;

{% hint style="warning" %}
Debes almacenar el estado <mark style="color:$success;">`threeDSRequired`</mark> junto con <mark style="color:$success;">`pvThreedsId`</mark> y <mark style="color:$success;">`referenceId`</mark>.
{% endhint %}

2. Cuando el usuario envía el formulario de pago completo, verificas el estado almacenado.&#x20;
   * Si <mark style="color:$success;">`threeDSRequired`</mark> es <mark style="color:$success;">verdadero</mark>, procedes con la validación 3DS llamando a <mark style="color:$success;">`startThreeDSValidator`</mark> .
   * Si <mark style="color:$success;">`threeDSRequired`</mark> es <mark style="color:$danger;">falso</mark> y la verificación inicial fue aprobada, puedes proceder directamente con la transacción.

{% hint style="warning" %}
La llamada al método del SDK debe hacerse cada vez que cambien los campos de número de tarjeta o de vencimiento, con un debounce que el cliente considere adecuado.
{% endhint %}

{% hint style="info" %}
KMP mapea <mark style="color:$success;">`Boolean?`</mark> a <mark style="color:$success;">`KotlinBoolean?`</mark> en Swift. Usa <mark style="color:$success;">`.boolValue`</mark> para extraer el valor. De manera similar, <mark style="color:$success;">`Int`</mark> se mapea a <mark style="color:$success;">`Int32`</mark>.
{% endhint %}

```swift
import PayvalidaAntifraud

class PaymentViewModel: ObservableObject {
    @Published var isThreeDSRequired: Bool = false
    @Published var isAntiFraudApproved: Bool = false
    var antiFraudKountSessionId: String = ""
    var antiFraudPvThreedsId: String = ""
    var antiFraudReferenceId: String = ""
    var antiFraudFranchise: String = ""

    // Paso 1: Llama a esto con un debounce mientras el usuario escribe el número de tarjeta/vencimiento
    func performAntiFraudValidation() {
        Task {
            do {
                let antiFraudArgs = AntiFraudArgs(
                    token: "tu-token",
                    cardNumber: "4111111111111111",
                    expirationMonth: "12",
                    expirationYear: "25"
                )

                let response = try await sdk.startAntiFraudValidator(data: antiFraudArgs)

                // Almacena los resultados de la verificación antifraude.
                // Es posible que una transacción sea aprobada por la verificación antifraude
                // pero aún así requiera la validación 3DS como un paso de seguridad adicional.
                await MainActor.run {
                    self.isAntiFraudApproved = response.isApproved
                    self.isThreeDSRequired = response.threeDSRequired?.boolValue ?? false
                    self.antiFraudKountSessionId = response.data?.kountSessionId ?? ""
                    self.antiFraudPvThreedsId = response.data?.pvThreedsId ?? ""
                    self.antiFraudReferenceId = response.data?.referenceId ?? ""
                    self.antiFraudFranchise = response.data?.franchise ?? ""
                }

            } catch {
                print("Ocurrió un error durante la verificación antifraude: \(error)")
            }
        }
    }

    // Paso 2: Llama a esto cuando el usuario envíe el formulario de pago completo
    func onFormSubmit() {
        if isThreeDSRequired {
            // Si se requiere 3DS, comenzar la validación 3DS con los datos completos del formulario.
            perform3DSValidation()
        } else if isAntiFraudApproved {
            // Si no se requiere 3DS y la verificación antifraude fue aprobada,
            // procede con la transacción, enviando kountSessionId y franchise a tu backend.
        } else {
            // Maneja el caso en que la transacción no está aprobada y no requiere 3DS.
        }
    }

    // ...
}
```

### Validación 3DS

Cuando <mark style="color:$success;">`startAntiFraudValidator`</mark> retorna <mark style="color:$success;">`threeDSRequired = true`</mark>, debes pasar los valores <mark style="color:$success;">`pvThreedsId`</mark> y referenceId de esa respuesta al <mark style="color:$success;">`FormData`</mark>:

```swift
mport PayvalidaAntifraud

func perform3DSValidation() {
    Task {
        do {
            let formData = FormData(
                billAddrCity: "Bogotá",
                billAddrCountry: "Colombia",
                billAddrLine1: "some direction",
                billAddrLine2: "some direction",
                billAddrPostCode: "660001",
                billAddrState: "Cundinamarca",
                cardNumber: "4111111111111111",
                instalments: Int32(1),              // KMP Int se mapea a Int32 en Swift
                cvv: "123",
                di: "12341234",
                expirationMonth: "12",
                expirationYear: "25",
                lastName: "Doe",
                name: "John",
                token: "tu-token",
                typeDI: "CC",
                phoneNumber: "3001234567",
                phoneCountryCode: nil,
                email: "usuario@ejemplo.com",
                pvThreedsId: antiFraudPvThreedsId.isEmpty ? nil : antiFraudPvThreedsId,
                referenceId: antiFraudReferenceId.isEmpty ? nil : antiFraudReferenceId
            )

            let response = try await sdk.startThreeDSValidator(data: formData)

            if response.isApproved {
                // Manejar validación 3DS exitosa
            } else {
                // Manejar validación 3DS fallida
                if let errorDescription = response.error {
                    print("Error de validación: \(errorDescription)")
                }
            }
        } catch {
            print("Ocurrió un error durante la validación 3DS: \(error)")
        }
    }
}
```
