> For the complete documentation index, see [llms.txt](https://docs.complycube.com/documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.complycube.com/documentation/sdks/sdks-es/integraciones-moviles/android-sdk/integracion-basada-en-comprobaciones.md).

# Integración basada en comprobaciones

## Descripción general

Esta guía le muestra cómo integrar el **Android SDK** con ComplyCube utilizando el enfoque basado en comprobaciones, dándote control directo sobre cada paso de verificación individual.

<figure><img src="/files/e1abf1b76dcc47e6db4aef4727269eabf2653e30" alt=""><figcaption><p>Vista del SDK móvil</p></figcaption></figure>

{% hint style="warning" %}
Estás viendo la **basado en comprobaciones** guía del SDK: un enfoque que ofrece un control detallado, pero es más adecuado para **socios** o **casos de uso avanzados.**  Recomendamos usar **integración del flujo de trabajo** para la mayoría de las implementaciones.
{% endhint %}

## Flujo de integración

El SDK móvil se ejecuta en tu aplicación móvil, pero depende de tu backend para crear **tokens seguros**. Así es como funciona:

{% stepper %}
{% step %}

#### **Crear un cliente**

Registrar un nuevo **cliente** (es decir, cliente) usando la API de ComplyCube.
{% endstep %}

{% step %}

#### **Generar un token del SDK**

Tu backend solicita un **token JWT** vinculado a ese cliente.
{% endstep %}

{% step %}

#### Inicializa el SDK en tu aplicación móvil

Pasa el token y la configuración al inicializador del SDK.
{% endstep %}

{% step %}

#### Captura documentos, vídeos y selfies

El SDK guía a tu cliente a través de los pasos requeridos.
{% endstep %}

{% step %}

#### Realizar comprobaciones

Los datos capturados se envían de forma segura a ComplyCube para las comprobaciones de verificación, y los resultados se entregan en tiempo real a través de la API o de webhooks.
{% endstep %}
{% endstepper %}

<figure><img src="/files/774a5bf3535ac0a2f47d3d2420252ea3d6bcd43d" alt=""><figcaption><p>Flujo de integración del SDK móvil</p></figcaption></figure>

## Guía de integración

Explore el código fuente y los proyectos de ejemplo en nuestro repositorio: [![GitHub](https://img.shields.io/badge/View%20on-GitHub-black?logo=github)](https://github.com/complycube/complycube-android-sdk).<br>

{% stepper %}
{% step %}

#### Instale el SDK

Nuestro SDK requiere los repositorios siguientes.

```java
repositories {
  mavenCentral()
}

dependencies {
    implementation "com.complycube:complycube-sdk:+"
}
```

{% endstep %}

{% step %}

#### **Crear un cliente**

Todo flujo de verificación comienza con un **cliente** (es decir, cliente). Usa la API para [crear el cliente](/documentation/api-reference/core-resources/clients/create-a-client.md).

Esto debe hacerse en tu **backend de la app móvil** servidor, no en la propia aplicación móvil.

**Ejemplo de solicitud**

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

```bash
curl -X POST https://api.complycube.com/v1/clients \
     -H 'Authorization: <YOUR_API_KEY>' \
     -H 'Content-Type: application/json' \
     -d '{
          "type": "person",
          "email": "john.doe@example.com",
          "personDetails":{
               "firstName": "John",
               "lastName" :"Doe"
          }
        }'
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const { ComplyCube } = require("@complycube/api");

const complycube = new ComplyCube({ apiKey: "<YOUR_API_KEY>" });

const client = await complycube.client.create({
  type: "person",
  email: "john.doe@example.com",
  personDetails: {
    firstName: "John",
    lastName: "Doe"
  }
});
```

{% endtab %}

{% tab title="Python" %}

```python
from complycube import ComplyCubeClient
cc_api = ComplyCubeClient(api_key='<YOUR_API_KEY>')

new_client = {
    'type':'person',
    'email':'john.doe@example.com',
    'personDetails': {
        'firstName':'John',
        'lastName':'Doe'
    }
}

client = cc_api.clients.create(**new_client)
```

{% endtab %}

{% tab title="PHP" %}

```php
use ComplyCube\ComplyCubeClient;

$ccapi = new ComplyCubeClient('<YOUR_API_KEY>');

$result = $ccapi->clients()->create([
    'type' => 'person',
    'email' => 'john@doe.com',
    'personDetails' => [
        'firstName' => 'John',
        'lastName' => 'Doe'
    ]
]);
```

{% endtab %}

{% tab title=".NET" %}

```csharp
using ComplyCube.Net;
using ComplyCube.Net.Resources.Clients;

var clientApi = new ClientApi(new ComplyCubeClient("<YOUR_API_KEY>"));
var newClient = new ClientRequest {
  type = "person",
  email = "john@doe.com",
  personDetails = new PersonDetails {
    firstName = "John",
    lastName = "Doe"
  }
}

var client = await clientApi.CreateAsync(newClient);
```

{% endtab %}
{% endtabs %}

**Ejemplo de respuesta**

La respuesta contendrá un `id` (el ID del cliente). Es necesario para el siguiente paso.

```json
{
    "id": "5eb04fcd0f3e360008035eb1",
    "type": "person",
    "email": "john.doe@example.com",
    "personDetails": {
        "firstName": "John",
        "apellido": "Doe"
    },
    "createdAt": "2020-01-04T17:24:29.146Z",
    "updatedAt": "2020-01-04T17:24:29.146Z"
}
```

{% hint style="info" %}
Consulta [Referencia de la API de clientes](/documentation/api-reference/core-resources/clients.md) para obtener más información.
{% endhint %}
{% endstep %}

{% step %}

#### Genera un token del SDK

Tu backend debe crear un **token del SDK** para cada nuevo flujo. Este token permite a los clientes enviar datos personales de forma segura desde tu app móvil a ComplyCube.

Los tokens tienen una vida útil corta y no deben reutilizarse.

**Ejemplo de solicitud**

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

```bash
curl -X POST https://api.complycube.com/v1/tokens \\
     -H 'Authorization: <YOUR_API_KEY>' \
     -H 'Content-Type: application/json' \
     -d '{
           "clientId":"CLIENT_ID",
           "appId": "com.complycube.SampleApp"
         }'
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const { ComplyCube } = require("@complycube/api");

const complycube = new ComplyCube({ apiKey: "<YOUR_API_KEY>" });

const token = await complycube.token.generate("CLIENT_ID", {
    appId: "com.complycube.SampleApp"
});
```

{% endtab %}

{% tab title="Python" %}

```python
from complycube import ComplyCubeClient

cc_api = ComplyCubeClient(api_key='<YOUR_API_KEY>')

token = cc_api.tokens.create('CLIENT_ID', appId='com.complycube.SampleApp')
```

{% endtab %}

{% tab title="PHP" %}

```php
use ComplyCube\ComplyCubeClient;

$ccapi = new ComplyCubeClient('<YOUR_API_KEY>');

$token = $ccapi->tokens()->generate('CLIENT_ID', 'com.complycube.SampleApp');
```

{% endtab %}

{% tab title=".NET" %}

```csharp
using ComplyCube.Net;
using ComplyCube.Net.Resources.SDKTokens;

var sdkTokenApi = new SDKTokenApi(new ComplyCubeClient("<YOUR_API_KEY>"));

var sdkTokenRequest = {
  clientId = "CLIENT_ID",
  appId = "com.complycube.SampleApp"
}

var sdkToken = await sdkTokenApi.GenerateToken(sdkTokenRequest);
```

{% endtab %}
{% endtabs %}

**Ejemplo de respuesta**

```json
{
    "token": "<CLIENT_TOKEN>"
}
```

{% hint style="info" %}
Consulta [Referencia de la API de tokens del SDK](/documentation/api-reference/other-resources/tokens.md) para obtener más información.
{% endhint %}
{% endstep %}

{% step %}

#### Prepara las etapas

Configura las etapas que deseas incluir en tu flujo.

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

```kotlin
val complyCubeBuilder = ComplyCubeSdk.Builder(this, callback =  { }).apply {
    withStages(
        Document(
            identityDocumentType = Passport(), DrivingLicence(),
            useLiveCaptureOnly = false
        ),
        SelfiePhoto()
    )
}
```

{% endtab %}

{% tab title="Java" %}

```java
IdentityDocumentType[] identityDocumentTypes;

identityDocumentTypes = new IdentityDocumentType[1];

identityDocumentTypes[0] = new DrivingLicence();

Document document = new Document(
    // tipo de documento
    null,
    // tipos de documentos
    identityDocumentTypes,
    // isGuidanceEnabled
    true,
    // useLiveCaptureOnly
    false,
    // isMLAssistanceEnabled
    true,
    // retryLimit
    5,
    // isNFCEnabled
    true
);
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

#### Inicialice el SDK

Ahora puedes inicializar un flujo. La secuencia de etapas que especifiques determina el orden en que tu cliente ve esas etapas.

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

```kotlin
val complyCubeBuilder = ComplyCubeSdk.Builder(this, callback =  { }).apply {
    withStages(
        Document(
            identityDocumentType = Passport(), DrivingLicence(),
            useLiveCaptureOnly = false
        ),
        SelfiePhoto()
    )
}.start(
    ClientAuth(
        token = "SDK_TOKEN",
        clientId = "CLIENT_ID"
    )
)
```

{% endtab %}

{% tab title="Java" %}

```java
ComplyCubeSdk.Builder complycubeFlow =
    new ComplyCubeSdk.Builder(this, result - > {});

complycubeFlow.withStages(
    document,
    new SelfiePhoto()
);

complycubeFlow.start(new ClientAuth(
    "SDK_TOKEN",
    "CLIENT_ID"
));
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

#### Realizar checks

Usando los `StageResults` devuelto por el flujo, puedes activar tu **backend móvil** para ejecutar las comprobaciones necesarias en tu cliente.

Por ejemplo, usa el resultado de una captura de selfie y documento de la siguiente manera:

* `StageResult.Document.Id` para ejecutar un [Comprobación de documento](https://docs.complycube.com/api-reference/check-types/document-check).
* `StageResult.Document.Id` y `StageResult.LivePhoto.Id` para ejecutar un [Comprobación de identidad](https://docs.complycube.com/api-reference/check-types/identity-check).

**Ejemplo de solicitud para una comprobación de documento**

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

```bash
curl -X POST https://api.complycube.com/v1/checks \
     -H 'Authorization: <YOUR_API_KEY>' \
     -H 'Content-Type: application/json' \
     -d '{
            "clientId":"CLIENT_ID",
            "type": "document_check",
            "documentId":"DOCUMENT_ID"
         }'
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const { ComplyCube } = require("@complycube/api");

const complycube = new ComplyCube({ apiKey: "<YOUR_API_KEY>" });

const check = await complycube.check.create("CLIENT_ID", {
    type: "document_check",
    documentId: "DOCUMENT_ID"
});
```

{% endtab %}

{% tab title="Python" %}

```python
from complycube import ComplyCubeClient

cc_api = ComplyCubeClient(api_key='<YOUR_API_KEY>')

check = cc_api.checks.create(
    "CLIENT_ID", 
    "document_check", 
    documentId="DOCUMENT_ID"
)
```

{% endtab %}

{% tab title="PHP" %}

```php
use ComplyCube\ComplyCubeClient;

$ccapi = new ComplyCubeClient('<YOUR_API_KEY>');

$result = $ccapi->checks()->create('CLIENT_ID', [
    'type' => 'document_check',
    'documentId' => 'DOCUMENT_ID'
]);
```

{% endtab %}

{% tab title=".NET" %}

```csharp
using ComplyCube.Net;
using ComplyCube.Net.Resources.Checks;

var checkApi = new CheckApi(new ComplyCubeClient("<YOUR_API_KEY>"));

var checkRequest = new CheckRequest {
  clientId = "CLIENT_ID",
  type = "document_check",
  documentId = "DOCUMENT_ID"
};

var check = await checkApi.CreateAsync(checkRequest);
```

{% endtab %}
{% endtabs %}

Si has [configurado webhooks](https://docs.complycube.com/api-reference/other-resources/webhooks/create-a-webhook) como se describe en nuestra [guía de webhooks](https://docs.complycube.com/documentation/guides/webhooks), se te notificará una vez que un check se complete.

Para recuperar los resultados del check, puedes realizar una solicitud GET de [check](https://docs.complycube.com/api-reference/checks/get-a-check).
{% endstep %}

{% step %}

#### Recuperar los resultados de la verificación

Tu backend móvil puede recuperar todos los resultados de las comprobaciones usando nuestra API.

Todas nuestras comprobaciones son **asíncronas.** Si has [configurado webhooks](https://docs.complycube.com/api-reference/other-resources/webhooks/create-a-webhook) como se describe en nuestra [guía de webhooks](https://docs.complycube.com/documentation/guides/webhooks), se te notificará una vez que un check se complete.

Para recuperar los resultados del check, puedes realizar una solicitud GET de [check](https://docs.complycube.com/api-reference/checks/get-a-check).

**Ejemplo de solicitud**

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

```bash
curl -X GET https://api.complycube.com/v1/checks/{:checkId} \\
     -H 'Authorization: <YOUR_API_KEY>' 
```

{% endtab %}

{% tab title="Node.js" %}

```javascript
const { ComplyCube } = require("@complycube/api");

const complycube = new ComplyCube({ apiKey: "<YOUR_API_KEY>" });

const check = await complycube.check.get("CHECK_ID");
```

{% endtab %}

{% tab title="Python" %}

```python
from complycube import ComplyCubeClient

cc_api = ComplyCubeClient(api_key='<YOUR_API_KEY>')

check = cc_api.checks.get('CHECK_ID')
```

{% endtab %}

{% tab title="PHP" %}

```php
use ComplyCube\ComplyCubeClient;

$ccapi = new ComplyCubeClient('<YOUR_API_KEY>');

$check = $ccapi->checks()->get('CHECK_ID');
```

{% endtab %}

{% tab title=".NET" %}

```csharp
using ComplyCube.Net;
using ComplyCube.Net.Resources.Checks;

var checkApi = new CheckApi(new ComplyCubeClient("<YOUR_API_KEY>"));

var check = await checkApi.GetAsync("CHECK_ID");
```

{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

## Etapas

Cada etapa del flujo puede personalizarse para crear el recorrido ideal para tus clientes.

El fragmento a continuación muestra cómo configurar un flujo personalizado utilizando el SDK móvil de ComplyCube.

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

```kotlin
var complycubeFlow = ComplyCubeSdk.Builder(this, callback = ...)
  .withSDKToken("SDK_Token")
  .withClientId("CLIENT_ID")
  .withStages(
    Welcome(...),
    Consent(...),
    Document(...),
    SelfiePhoto(...),
    AddressCapture(...),
    ProofOfAddress(...),
    Complete(...)
  )
  .withLookAndFeel(...)
  .withCustomLanguage(...)

complycubeFlow.start()
```

{% endtab %}

{% tab title="Java" %}

```java
complycubeFlow.withStages(
    new Welcome(...),
    new UserConsent(...),
    new Document(...),
    new SelfiePhoto(...),
    new AddressCapture(...),
    new ProofOfAddress(...),
    new Complete(...)
);

complycubeFlow.withLookAndFeel(...);
complycubeFlow.withCustomLanguage(..);
```

{% endtab %}
{% endtabs %}

### **Bienvenido**

La pantalla de bienvenida siempre se muestra primero en el flujo de verificación. Muestra un mensaje de bienvenida junto con un resumen de las etapas configuradas que el usuario completará.

Puedes personalizar el título de la pantalla para que se alinee con el tono y la identidad de tu aplicación.

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

```kotlin
var welcomeStage = Welcome(
    title = "Título personalizado de pantalla",
    message = "Mensaje de bienvenida personalizado."
)
```

{% endtab %}

{% tab title="Java" %}

```java
 Welcome welcome = new Welcome(
     "Título personalizado de pantalla",
     "Mensaje de bienvenida personalizado",
     null
 );
```

{% endtab %}
{% endtabs %}

### **Consentimiento**

Esta etapa se utiliza para recopilar el consentimiento explícito del usuario antes de continuar con el flujo de verificación. Le ayuda a cumplir con los requisitos regulatorios y de conformidad cuando corresponda.

Puede personalizar el título y el mensaje de la pantalla para que se adapten a sus necesidades legales o de marca.

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

```kotlin
var consentStage = Consent(
    title = "Título personalizado de la pantalla de consentimiento"
)
```

{% endtab %}

{% tab title="Java" %}

```java
UserConsent userConsent = new UserConsent(
    "Título personalizado de la pantalla de consentimiento",
    null,
    null
);
```

{% endtab %}
{% endtabs %}

### **Selfie en foto y video**

Puede solicitar una foto selfie  (es decir, una [Foto en vivo](/documentation/api-reference/core-resources/live-photos.md)) o un video selfie (es decir, un [Video en vivo](/documentation/api-reference/core-resources/live-videos.md)) del cliente como parte del proceso de verificación biométrica.

* **Foto**: Captura una imagen estática y realiza una comprobación pasiva de vitalidad antes de permitir el envío.
* **Video**: Graba un video corto en el que el usuario completa un reto en pantalla (p. ej., movimiento de la cabeza o una frase hablada).

{% hint style="warning" %}
Si intenta añadir ambos tipos de etapas, el SDK lanzará un **`ComplyCubeErrorCode.BiometricStageCount`** error que indica que hay varias etapas en conflicto.
{% endhint %}

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

```kotlin
var selfiePhoto = SelfiePhoto(
    // Habilita la asistencia de ML durante la captura
    isMLAssistantEnabled = false
)
```

{% endtab %}

{% tab title="Java" %}

```java
SelfiePhoto selfiePhoto = new SelfiePhoto(
    // isGuidanceEnabled
    true,
    // useLiveCaptureOnly
    true,
    // isMLAssistanceEnabled
    false,
    // retryLimit
    5
);
```

{% endtab %}
{% endtabs %}

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

```kotlin
var selfieVideo = SelfieVideo(
    // Habilita la asistencia de ML durante la captura
    isMLAssistantEnabled = false
)
```

{% endtab %}

{% tab title="Java" %}

```java
 SelfieVideo selfieVideo = new SelfieVideo(
     // isGuidanceEnabled
     true,
     // isMLAssistanceEnabled
     false,
     // retryLimit
     5
 );
```

{% endtab %}
{% endtabs %}

### **Documento**

La fase de Documento permite a los usuarios seleccionar y capturar un documento de identidad para su verificación (p. ej., pasaporte, documento de identidad, permiso de residencia). Puede personalizar estas pantallas para:

* Limitar el alcance de los tipos de documento que el cliente puede seleccionar, por ejemplo, solo Pasaporte.
* Configurar los países emisores de documentos permitidos para cada tipo de documento.
* Añadir o quitar la captura automatizada mediante asistencia inteligente.
* Mostrar u ocultar las pantallas de instrucciones antes de la captura.
* Establecer un límite de reintentos para permitir que los clientes avancen en el recorrido independientemente de la calidad de la captura.

{% hint style="info" %}
Si proporciona solo un tipo de documento, se omitirá la pantalla de selección del tipo de documento. La pantalla de selección de país se omitirá si proporciona un único país para un tipo de documento determinado.
{% endhint %}

Puede controlar si las pantallas de instrucciones se muestran antes de cada captura con cámara habilitando o deshabilitando el modo de guía. Deshabilite la guía solo si sus usuarios ya están claramente informados sobre los pasos de captura, ya que estas pantallas ayudan a reducir los errores de los usuarios y a mejorar la calidad de la captura.

{% hint style="info" %}
Tenga en cuenta que el `retryLimit` que configure aquí tendrá prioridad sobre el límite de reintentos que se haya establecido globalmente en sus [configuración de automatización](https://portal.complycube.com/automations).
{% endhint %}

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

```kotlin
var documentStage = Document(
    // Establece los tipos de documentos y limita los países habilitados
    Passport(), DrivingLicence((Country.GB, Country.US)),

    // Habilita o deshabilita orientación adicional para el usuario
    isGuidanceEnabled = true,

    // Habilita o deshabilita la capacidad de subir una imagen desde un archivo
    useLiveCaptureOnly = true,

    // Habilita la asistencia de ML durante la captura
    isMLAssistantEnabled = true,
    
    // Establece un máximo de intentos de comprobación de calidad antes de cargar
    retryLimit = 3
)
```

{% endtab %}

{% tab title="Java" %}

```java
IdentityDocumentType[] identityDocumentTypes;

identityDocumentTypes = new IdentityDocumentType[1];

identityDocumentTypes[0] = new DrivingLicence();

Document document = new Document(
    null,
    identityDocumentTypes, // tipos de documentos
    true, // isGuidanceEnabled
    false, // useLiveCaptureOnly
    true, // isMLAssistanceEnabled
    5, // retryLimit
    true // isNFCEnabled
);
```

{% endtab %}
{% endtabs %}

### Captura NFC

El SDK móvil de ComplyCube admite lectura basada en NFC **chip RFID** la lectura de documentos de identidad equipados con chips integrados. Esto permite una extracción de datos segura y una autenticación documental de alta fiabilidad.

{% hint style="info" %}
Póngase en contacto con su **Gerente de cuenta** o [soporte](https://support.complycube.com/hc/en-gb/requests/new) para obtener acceso a nuestro SDK móvil con compatibilidad NFC.
{% endhint %}

#### Requisitos previos

1. Comienza añadiendo tus credenciales de acceso para el repositorio del SDK habilitado para NFC de ComplyCube en el `gradle.properties` archivo de tu **aplicación móvil**:

```gradle
artifactory_user= "USERNAME"
artifactory_password= "ENCRYPTED PASS"
artifactory_contextUrl= https://complycuberepo.jfrog.io/artifactory
```

2. Luego, actualiza el nivel de tu proyecto `build.gradle` archivo con la configuración Maven del repositorio del SDK de ComplyCube:

```gradle
buildscript {
    repositories {
        ...
    }
    dependencies {
        ....
        // Comprueba la última versión aquí: 
        // http://plugins.gradle.org/plugin/com.jfrog.artifactory
        classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4+"
    }
    ...
}

allprojects {
    apply plugin: "com.jfrog.artifactory"
    ...
}

artifactory {
  contextUrl = "${artifactory_contextUrl}"  
  resolve {
    repository {
      repoKey = 'cc-gradle-release'
      username = "${artifactory_user}"
      password = "${artifactory_password}"
      maven = true
    }
  }
}
```

3. Actualice el nivel de su módulo `build.gradle` archivo con la dependencia del SDK:

```gradle
dependencies {
    implementation "com.complycube:complycube-sdk:+"
    implementation "com.complycube:nfc-plugin:+"
}
```

#### Habilitar captura NFC

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

```kotlin
var documentStage = Document(
    // Añade esta propiedad para habilitar NFC
    isNFCEnabled = true,
)
```

{% endtab %}

{% tab title="Java" %}

```java
IdentityDocumentType[] identityDocumentTypes;

identityDocumentTypes = new IdentityDocumentType[1];

identityDocumentTypes[0] = new Passport();

Document document = new Document(
    null,
    // tipos de documentos
    identityDocumentTypes,
    // isGuidanceEnabled
    true,
    // useLiveCaptureOnly
    false,
    // isMLAssistanceEnabled
    true,
    // retryLimit
    5,
    // isNFCEnabled
    true
);
```

{% endtab %}
{% endtabs %}

### **Captura de dirección**

Esta etapa permite a los usuarios introducir manualmente su dirección residencial. Puede personalizarla para:

* Restringir la entrada a países específicos
* Activar o desactivar la función de autocompletado de direcciones para una introducción más rápida y precisa

{% tabs %}
{% tab title="Kotlin" %}
{% code fullWidth="false" %}

```kotlin
var addressCaptureStage = AddressCapture(
    // Esto habilita nuestro autocompletado de direcciones
    useAutoComplete = true,
    
    // Una lista de países aceptables para la función de captura de direcciones
    allowedCountries = setOf(Country.GB,Country.US)
)
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}

```java
Set<Country> countries = new HashSet<> ();

countries.add(Country.GB);
countries.add(Country.US);

AddressCapture addressCapture = new AddressCapture(
    // useAutoComplete
    true,
    // allowedCountries
    countries
);
```

{% endtab %}
{% endtabs %}

### **Comprobante de domicilio**

Esta etapa permite a los clientes enviar un documento que verifique su dirección residencial. Puede configurar qué tipos de documentos se aceptan, como facturas de servicios públicos o extractos bancarios, y elegir si los clientes pueden cargar un archivo o si deben capturar el documento en vivo usando la cámara de su dispositivo.

{% hint style="info" %}
De forma predeterminada, esta etapa incluye la **etapa de captura de dirección** con el autocompletado habilitado para ayudar a los usuarios durante la entrada. El autocompletado se puede deshabilitar si no es necesario.
{% endhint %}

{% tabs %}
{% tab title="Kotlin" %}
{% code fullWidth="false" %}

```kotlin
var poaStage = ProofOfAddress(
    // Una lista de tipos de documento admitidos que pueden enviarse
    UtilityBill(), BankStatement(),

    // Cuando se deshabilita, el cliente se verá obligado a realizar una captura en vivo
    useLiveCaptureOnly = false,

    // Esto habilita la captura de dirección durante el flujo de comprobante de domicilio
    isAddressCaptureEnabled = false
    ...
)
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}

```java
LinkedHashSet<ProofOfAddressDocumentType> documentTypes =
    new LinkedHashSet<ProofOfAddressDocumentType> ();

documentTypes.add(new UtilityBill());
documentTypes.add(new BankStatement());

ProofOfAddress poaStage = new ProofOfAddress(
    documentTypes,
    // isGuidanceEnabled
    true,
    // useLiveCaptureOnly
    false,
    // isMLAssistanceEnabled
    true,
    // retryLimit
    5,
    // isAddressCaptureEnabled
    false
);
```

{% endtab %}
{% endtabs %}

### **Finalización**

Puede incluir una etapa de finalización al final del flujo para confirmar que el proceso se ha completado correctamente. Esta pantalla proporciona un punto final claro para el usuario y puede personalizarse para mostrar un mensaje de confirmación o los siguientes pasos.

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

```kotlin
val completionStage = Complete(
    title = "¡Gracias!",
    message = "Tu envío de KYC se ha completado"
)
```

{% endtab %}

{% tab title="Java" %}

```java
Complete complete = new Complete(
    "Título personalizado de finalización",
    "Mensaje personalizado de finalización",
    null
);
```

{% endtab %}
{% endtabs %}

## Identidad de marca

El SDK te permite personalizar la interfaz de usuario para que coincida con la identidad visual de tu aplicación. Puedes definir los colores principal y de acento durante la configuración para alinear el flujo de verificación con las directrices de tu marca. Obtén más información sobre nuestras **propiedades de apariencia** (ver más abajo).

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

```kotlin
complycubeFlow.withLookAndFeel(
    lookAndFeel = LookAndFeel(
        primaryButtonBgColor = Color.RED,
        /* También puede establecerse en UIInterfaceStyle.LIGHT 
        o UIInterfaceStyle.INHERITED */
        uiInterfaceStyle = UIInterfaceStyle.DARK
    )
)
```

{% endtab %}

{% tab title="Java" %}

```java
complycubeFlow.withLookAndFeel(new LookAndFeel(
    // primaryButtonBGColor
    Color.parseColor("#FF0000"),
    // uiInterfaceStyle
    UIInterfaceStyle.DARK,
    ...
));
```

{% endtab %}
{% endtabs %}

<details>

<summary>Propiedades de apariencia</summary>

<table><thead><tr><th width="371.70703125">Propiedad de apariencia</th><th>Descripción</th></tr></thead><tbody><tr><td><code>primaryButtonBgColor</code></td><td>Color de fondo del botón de acción principal.</td></tr><tr><td><code>primaryButtonTextColor</code></td><td>Color del texto del botón de acción principal.</td></tr><tr><td><code>primaryButtonBorderColor</code></td><td>Color del borde del botón de acción principal.</td></tr><tr><td><code>secondaryButtonBgColor</code></td><td>Color de fondo del botón secundario.</td></tr><tr><td><code>secondaryButtonPressedBgColor</code></td><td>Color de fondo del botón de acción secundaria al pulsarlo.<br><br><em>No es compatible con Android.</em></td></tr><tr><td><code>secondaryButtonTextColor</code></td><td>Color del texto del botón de acción secundaria.</td></tr><tr><td><code>secondaryButtonBorderColor</code></td><td>Color del borde del botón de acción secundaria.</td></tr><tr><td><code>documentTypeSelectorBgColor</code></td><td>Color del botón de selección del tipo de documento.</td></tr><tr><td><code>documentTypeSelectorBorderColor</code></td><td>Color del borde del botón de selección del tipo de documento.</td></tr><tr><td><code>documentTypeSelectorTitleTextColor</code></td><td>Color del texto del título de selección del tipo de documento.</td></tr><tr><td><code>documentTypeSelectorDescriptionTextColor</code></td><td>Color del texto de la descripción de selección del tipo de documento.</td></tr><tr><td><code>documentTypeSelectorIconColor</code></td><td>Color del icono de selección del tipo de documento.</td></tr><tr><td><code>bodyTextColor</code></td><td>Color del texto del cuerpo de la pantalla.</td></tr><tr><td><code>linkButtonTextColor</code></td><td>Color de los enlaces.<br><br><em>No es compatible con Android.</em></td></tr><tr><td><code>headingTextColor</code></td><td>Color del texto del título principal.</td></tr><tr><td><code>subheadingTextColor</code></td><td>Color del texto del subtítulo.</td></tr><tr><td><code>infoPanelTitleColor</code></td><td>Color del título del panel de información.</td></tr><tr><td><code>infoPanelDescriptionTextColor</code></td><td>Color del texto de la descripción del panel de información.</td></tr><tr><td><code>infoPanelBgColor</code></td><td>Color de fondo del panel de información.</td></tr><tr><td><code>infoPanelIconColor</code></td><td>Color del icono del panel de información.</td></tr><tr><td><code>errorPanelTitleColor</code></td><td>Color del título del panel de error.</td></tr><tr><td><code>errorPanelDescriptionTextColor</code></td><td>Color del texto de la descripción del panel de error.</td></tr><tr><td><code>errorPanelBgColor</code></td><td>Color de fondo del panel de error.</td></tr><tr><td><code>errorPanelIconColor</code></td><td>Color del icono del panel de error.</td></tr><tr><td><code>cameraButtonBgColor</code></td><td>Color de fondo del botón de captura de la cámara.</td></tr><tr><td><code>uiInterfaceStyle</code></td><td>Configura el SDK para usar el modo oscuro, el modo claro o el heredado del sistema.</td></tr></tbody></table>

</details>

## Localización

El SDK es compatible con varios idiomas, incluidos los que se enumeran a continuación.

{% columns %}
{% column %}

* Árabe - `ar` 🇦🇪
* Chino (simplificado) - `zh` 🇨🇳
* Chino (tradicional) - `hk` 🇨🇳
* Neerlandés - `nl` 🇳🇱
* Inglés - `en` 🇺🇸
* Francés - `fr` 🇫🇷
* Alemán - `de` 🇩🇪
* Hindi - `hi` 🇮🇳
* Indonesio -  `id` 🇮🇩
* Italiano - `it` 🇮🇹
  {% endcolumn %}

{% column %}

* Japonés -  `ja` 🇯🇵
* Coreano -  `ko` 🇰🇷
* Noruego - `no` 🇳🇴
* Polaco - `po` 🇵🇱
* Portugués - `pt` 🇵🇹
* Español - `es` 🇪🇸
* Sueco - `sv` 🇸🇪
* Tailandés -  `th` 🇹🇭
* Vietnamita -  `vi` 🇻🇳
* y más...
  {% endcolumn %}
  {% endcolumns %}

## Gestión de resultados

Para ejecutar comprobaciones de verificación, debe implementar los **éxito**, **cancelado**, y **error** callbacks.

Al completarse correctamente (`onSuccess`), puede activar [solicitudes de comprobación](/documentation/api-reference/core-resources/checks/create-a-check.md) desde su backend utilizando los IDs de recursos devueltos en el objeto de resultado. Estos IDs corresponden a los activos cargados (p. ej., documentos, selfies) y pueden usarse para iniciar comprobaciones de verificación a través de la API de ComplyCube.

Si el usuario abandona el flujo antes de completarlo, el `onCancelled` callback se invoca con un motivo descriptivo que indica por qué se canceló la sesión (p. ej., salida del usuario, tiempo de espera agotado, permiso denegado)

{% hint style="info" %}
En algunos casos, el cliente puede cancelar el flujo después de completar una o más etapas de captura. Si esto ocurre, es posible que cualquier dato capturado antes de la cancelación, como documentos o medios biométricos, ya se haya cargado en su registro de cliente.
{% endhint %}

Si el SDK encuentra un problema, el `onError` callback se activa con un `ComplyCubeError` objeto que contiene el tipo de error y el mensaje. Consulte los **códigos de error** (véase a continuación) para obtener una lista completa de los posibles casos de error.

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

```kotlin
//Registre un controlador de resultados para procesar el resultado del flujo.
var complycubeFlow =
    ComplyCubeSdk.Builder(
        this,
        callback = { result ->
            when (result) {
                is Result.Success -> { 
                /*
                Gestión de resultados satisfactorios:
                Nuestro flujo predeterminado incluye tres componentes: un documento de identidad,
                una selfie (foto en vivo) y un comprobante de domicilio. Tras una 
                la finalización, el 'Result' contendrá un array de resultados de etapa.
                Cada resultado de etapa proporciona el ID del elemento cargado:
                  - 'StageResult.Document.Id': el ID del documento cargado.
                  - 'StageResult.LivePhoto.Id': el ID de la foto en vivo cargada.
                  - 'StageResult.ProofOfAddress.Id': el ID del documento de comprobante de domicilio cargado.
                */
                }
                is Result.Cancelled -> { /* Gestionar resultado cancelado */ }
                is Result.Error -> {
                    // Gestionar errores
                    when (result.errorCode) {
                        ComplyCubeErrorCode.UploadError -> {
                            // Gestionar error de carga
                        }
                        ComplyCubeErrorCode.BiometricStageCount -> {
                            // Gestionar error de BiometricStageCount
                        }
                        // ...otros controladores de errores
                    }
                }
                else -> {}
            }
        }
    )

complycubeFlow.start(clientAuth)
```

{% endtab %}

{% tab title="Java" %}

```java
//Registre un controlador de resultados para procesar el resultado del flujo.
ComplyCubeSdk.Builder complycubeFlow = new ComplyCubeSdk.Builder(this, result -> {
    if (result instanceof Result.Success) {
        /*
        Gestión de resultados satisfactorios:
        Nuestro flujo predeterminado incluye tres componentes: un documento de identidad,
        una selfie (foto en vivo) y un comprobante de domicilio. Tras una 
        la finalización, el 'Result' contendrá un array de resultados de etapa.
        Cada resultado de etapa proporciona el ID del elemento cargado:
          - 'StageResult.Document.Id': el ID del documento cargado.
          - 'StageResult.LivePhoto.Id': el ID de la foto en vivo cargada.
          - 'StageResult.ProofOfAddress.Id': el ID del documento de comprobante de domicilio cargado.
        */
    } else if (result instanceof Result.Error) {
        switch (((Result.Error) result).getErrorCode()) {
            case ComplyCubeErrorCode.UploadError.INSTANCE:
                // Gestionar error de carga
                break;
            case ComplyCubeErrorCode.BiometricStageCount.INSTANCE:
                // Gestionar error de BiometricStageCountError
                break;
                // ... otros controladores de errores
            default:
        }
    } else if (result instanceof Result.Canceled) {
        // Gestionar resultado cancelado
    }
    return null;
});
```

{% endtab %}
{% endtabs %}

<details>

<summary>Códigos de error</summary>

<table data-full-width="false"><thead><tr><th width="312.48828125">Tipo de error</th><th>Descripción</th></tr></thead><tbody><tr><td><code>BiometricStageCount</code></td><td>La configuración incluye duplicados <strong>foto de selfie</strong> o <strong>video de selfie</strong> etapas.</td></tr><tr><td><code>Cancelado</code></td><td>El cliente canceló el flujo y salió del SDK (activó la <code>onCancelled</code> devolución de llamada).</td></tr><tr><td><code>Conectividad</code></td><td>Se ha producido un error de red.</td></tr><tr><td><code>DocumentMandatory</code></td><td>Una <strong>etapa de documento</strong> es obligatorio según las etapas configuradas, pero no se ha incluido.</td></tr><tr><td><code>ExpiredToken</code></td><td>El token del SDK ha expirado. Genere un nuevo token y reinicie el flujo.</td></tr><tr><td><code>FlowError</code></td><td>Se produjo un error irrecuperable durante el flujo.</td></tr><tr><td><code>InvalidCountryCode</code></td><td>Se proporcionó un código de país no válido.</td></tr><tr><td><code>JailBroken</code></td><td>El SDK no puede ejecutarse en este dispositivo porque ha sido liberado de restricciones (jailbreak) o comprometido.</td></tr><tr><td><code>NoDiskAccess</code></td><td>El cliente denegó los permisos de acceso al disco requeridos por el SDK.</td></tr><tr><td><code>NoDocumentTypes</code></td><td>Una <strong>etapa de documento</strong> se inicializó sin especificar ningún tipo de documento.</td></tr><tr><td><code>NoResult</code></td><td>No se devolvió ningún resultado a la devolución de llamada. Si esto persiste, póngase en contacto con soporte.</td></tr><tr><td><code>NoUserConsent</code></td><td>El cliente no ha dado su consentimiento para continuar con el flujo del SDK.</td></tr><tr><td><code>NotAuthorized</code></td><td>El SDK intentó acceder a un extremo para el que no está autorizado.</td></tr><tr><td><code>Desconocido</code></td><td>Se produjo un error inesperado. Si esto ocurre repetidamente, contacte con soporte.</td></tr><tr><td><code>UnsupportedCountryTypeCombination</code></td><td>La combinación de país y tipo de documento seleccionada no es compatible.</td></tr><tr><td><code>UnsupportedDocumentType</code></td><td>El tipo de documento proporcionado no es compatible.</td></tr><tr><td><code>UploadError</code></td><td>Se produjo un error al cargar un documento o una selfie.</td></tr><tr><td><code>UploadRequireGuidance</code></td><td>Si <code>useLiveCaptureOnly</code> está configurado en <code>false</code>, la guía debe habilitarse configurando <code>isGuidanceEnabled</code> en <code>true</code>.</td></tr></tbody></table>

</details>

## Seguimiento de eventos

El SDK registra una variedad de **eventos** durante todo el flujo de verificación, cubriendo todas las interacciones clave del usuario en cada etapa. Consulte a continuación la lista de eventos.

Si necesita implementar analíticas personalizadas, puede conectarse a estos eventos y activar su propia lógica de seguimiento en consecuencia.

Para incorporar su propio seguimiento, defina una función y aplíquela usando `withEventHandler` al inicializar el `Builder`:

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

```kotlin
complycubeBuilder.withEventHandler(true) { event ->
    // Inserte aquí el seguimiento personalizado de usuarios
}
```

{% endtab %}

{% tab title="Java" %}

```java
complycubeFlow.withEventHandler(true, analyticsEvent ->
    // Inserte aquí el seguimiento personalizado de usuarios
);
```

{% endtab %}
{% endtabs %}

<details>

<summary>Eventos</summary>

| Evento                                                                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <p><code>INTRODUCCIÓN</code><br><br>El cliente llegó a la pantalla de introducción.</p>                                                                                                                                                          |
| <p><code>ETAPA\_DE\_CONSENTIMIENTO</code><br><br>El cliente llegó a la pantalla de consentimiento.</p>                                                                                                                                           |
| <p><code>ADVERTENCIA\_DE\_ETAPA\_DE\_CONSENTIMIENTO</code><br><br>El cliente intentó salir sin dar su consentimiento.</p>                                                                                                                        |
| <p><code>PERMISO\_DE\_ACCESO\_A\_LA\_CÁMARA</code><br><br>El cliente llegó a la pantalla de solicitud de permiso de la cámara.</p>                                                                                                               |
| <p><code>ETAPA\_DE\_GUÍA\_DE\_CAPTURA\_DE\_DOCUMENTO</code><br><br>El cliente llegó a la pantalla de guía de captura de documentos.</p>                                                                                                          |
| <p><code>ETAPA\_DE\_TIPO\_DE\_DOCUMENTO</code><br><br>El cliente llegó a la pantalla de selección del tipo de documento para una captura de documento.</p>                                                                                       |
| <p><code>ETAPA\_DE\_SELECCIÓN\_DE\_PAÍS</code><br><br>El cliente llegó a la pantalla de selección de país para una captura de documento.</p>                                                                                                     |
| <p><code>ETAPA\_DE\_CÁMARA\_DE\_DOCUMENTO\_DE\_UNA\_CARA</code><br><br>El cliente llegó a la etapa de captura con cámara para un documento de identificación de una sola cara.</p>                                                               |
| <p><code>ETAPA\_DE\_CÁMARA\_MANUAL\_DE\_DOCUMENTO\_DE\_UNA\_CARA</code><br><br>El cliente llegó a la pantalla de captura manual con cámara de un documento de identificación de una sola cara.</p>                                               |
| <p><code>ETAPA\_DE\_REVISIÓN\_DE\_CALIDAD\_DE\_DOCUMENTO\_DE\_UNA\_CARA</code><br><br>El cliente llegó a la pantalla de vista previa de calidad para un documento de identificación de una sola cara.</p>                                        |
| <p><code>ETAPA\_DE\_CÁMARA\_DELANTERA\_DE\_DOCUMENTO\_DE\_DOS\_CARAS</code><br><br>El cliente llegó a la pantalla de captura con cámara para la cara frontal de un documento de identificación de dos caras.</p>                                 |
| <p><code>ETAPA\_DE\_CÁMARA\_MANUAL\_DELANTERA\_DE\_DOCUMENTO\_DE\_DOS\_CARAS</code><br><br>El cliente llegó a la pantalla de captura manual con cámara para la cara frontal de un documento de identificación de dos caras.</p>                  |
| <p><code>ETAPA\_DE\_REVISIÓN\_DE\_CALIDAD\_DELANTERA\_DE\_DOCUMENTO\_DE\_DOS\_CARAS</code><br><br>El cliente llegó a la pantalla de vista previa de calidad para la cara frontal de un documento de identificación de dos caras.</p>             |
| <p><code>ETAPA\_DE\_CÁMARA\_POSTERIOR\_DE\_DOCUMENTO\_DE\_DOS\_CARAS</code><br><br>El cliente llegó a la pantalla de captura con cámara para la cara posterior de un documento de identificación de dos caras.</p>                               |
| <p><code>ETAPA\_DE\_CÁMARA\_MANUAL\_POSTERIOR\_DE\_DOCUMENTO\_DE\_DOS\_CARAS</code><br><br>El cliente llegó a la pantalla de captura manual con cámara para la cara posterior de un documento de identificación de dos caras.</p>                |
| <p><code>ETAPA\_DE\_REVISIÓN\_DE\_CALIDAD\_POSTERIOR\_DE\_DOCUMENTO\_DE\_DOS\_CARAS</code><br><br>El cliente llegó a la pantalla de vista previa de calidad para la cara posterior de un documento de identificación de dos caras.</p>           |
| <p><code>ETAPA\_DE\_GUÍA\_DE\_CAPTURA\_DE\_SELFIE</code><br><br>El cliente llegó a la pantalla de guía de captura de selfie.</p>                                                                                                                 |
| <p><code>ETAPA\_DE\_CÁMARA\_DE\_SELFIE</code><br><br>El cliente llegó a la pantalla de cámara para capturar la foto de selfie.</p>                                                                                                               |
| <p><code>ETAPA\_DE\_CÁMARA\_MANUAL\_DE\_SELFIE</code><br><br>El cliente llegó a la pantalla de cámara para capturar manualmente la foto de selfie.</p>                                                                                           |
| <p><code>ETAPA\_DE\_REVISIÓN\_DE\_CALIDAD\_DE\_SELFIE</code><br><br>El cliente llegó a la pantalla de revisión de la foto capturada de la selfie.</p>                                                                                            |
| <p><code>ETAPA\_DE\_CÁMARA\_DE\_VIDEO\_SELFIE</code><br><br>El cliente llegó a la pantalla de cámara para selfie en video.</p>                                                                                                                   |
| <p><code>ETAPA\_DE\_CÁMARA\_MANUAL\_DE\_VIDEO\_SELFIE</code><br><br>El cliente llegó a la pantalla de captura manual con cámara para una selfie en video.</p>                                                                                    |
| <p><code>ETAPA\_DE\_ACCIÓN\_DE\_VIDEO\_SELFIE\_UNO</code><br><br>El cliente llegó a la primera acción en una captura de selfie en video.</p>                                                                                                     |
| <p><code>ETAPA\_DE\_ACCIÓN\_DE\_VIDEO\_SELFIE\_DOS</code><br><br>El cliente llegó a la segunda acción en una captura de selfie en video.</p>                                                                                                     |
| <p><code>ETAPA\_DE\_REVISIÓN\_DE\_CALIDAD\_DE\_VIDEO\_SELFIE</code><br><br>El cliente llegó a la pantalla de cámara para captura manual de selfie en video.</p>                                                                                  |
| <p><code>ETAPA\_DE\_GUÍA\_DE\_CAPTURA\_DE\_COMPROBANTE\_DE\_DOMICILIO</code><br><br>El cliente llegó a la pantalla de guía de captura de comprobante de domicilio.</p>                                                                           |
| <p><code>ETAPA\_DE\_TIPO\_DE\_DOCUMENTO\_DE\_COMPROBANTE\_DE\_DOMICILIO</code><br><br>El cliente llegó a la pantalla de selección del tipo de documento para una captura de comprobante de domicilio.</p>                                        |
| <p><code>ETAPA\_DE\_SELECCIÓN\_DE\_PAÍS\_DE\_COMPROBANTE\_DE\_DOMICILIO</code><br><br>El cliente llegó a la pantalla de selección de país para una captura de comprobante de domicilio.</p>                                                      |
| <p><code>ETAPA\_DE\_CÁMARA\_DE\_COMPROBANTE\_DE\_DOMICILIO\_DE\_UNA\_CARA</code><br><br>El cliente llegó a la etapa de captura con cámara para un comprobante de domicilio de una sola cara.</p>                                                 |
| <p><code>ETAPA\_DE\_CÁMARA\_MANUAL\_DE\_COMPROBANTE\_DE\_DOMICILIO\_DE\_UNA\_CARA</code><br>El cliente llegó a la etapa de captura manual con cámara para un comprobante de domicilio de una sola cara.</p>                                      |
| <p><code>ETAPA\_DE\_REVISIÓN\_DE\_CALIDAD\_DE\_COMPROBANTE\_DE\_DOMICILIO\_DE\_UNA\_CARA</code><br><br>El cliente llegó a la pantalla de vista previa de calidad para un comprobante de domicilio de una sola cara.</p>                          |
| <p><code>ETAPA\_DE\_CÁMARA\_DELANTERA\_DE\_COMPROBANTE\_DE\_DOMICILIO\_DE\_DOS\_CARAS</code><br><br>El cliente llegó a la etapa de captura con cámara para la cara frontal de un comprobante de domicilio de dos caras.</p>                      |
| <p><code>ETAPA\_DE\_CÁMARA\_MANUAL\_DELANTERA\_DE\_COMPROBANTE\_DE\_DOMICILIO\_DE\_DOS\_CARAS</code><br>El cliente llegó a la etapa de captura manual con cámara para la cara frontal de un comprobante de domicilio de dos caras.</p>           |
| <p><code>ETAPA\_DE\_REVISIÓN\_DE\_CALIDAD\_DELANTERA\_DE\_COMPROBANTE\_DE\_DOMICILIO\_DE\_DOS\_CARAS</code><br>El cliente llegó a la pantalla de vista previa de calidad para la cara frontal de un comprobante de domicilio de dos caras.</p>   |
| <p><code>ETAPA\_DE\_CÁMARA\_POSTERIOR\_DE\_COMPROBANTE\_DE\_DOMICILIO\_DE\_DOS\_CARAS</code><br><br>El cliente llegó a la etapa de captura con cámara para la cara posterior de un comprobante de domicilio de dos caras.</p>                    |
| <p><code>ETAPA\_DE\_CÁMARA\_MANUAL\_POSTERIOR\_DE\_COMPROBANTE\_DE\_DOMICILIO\_DE\_DOS\_CARAS</code><br>El cliente llegó a la etapa de captura manual con cámara para la cara posterior de un comprobante de domicilio de dos caras.</p>         |
| <p><code>ETAPA\_DE\_REVISIÓN\_DE\_CALIDAD\_POSTERIOR\_DE\_COMPROBANTE\_DE\_DOMICILIO\_DE\_DOS\_CARAS</code><br>El cliente llegó a la pantalla de vista previa de calidad para la cara posterior de un comprobante de domicilio de dos caras.</p> |
| <p><code>ETAPA\_DE\_FINALIZACIÓN</code><br><br>El cliente ha llegado a la pantalla de finalización.</p>                                                                                                                                          |

</details>

## Gestión de vencimiento del token

Para gestionar la expiración del token de forma fluida, puedes proporcionar una función de devolución de llamada que genere un nuevo token del SDK cuando sea necesario. Esto permite que el flujo continúe sin interrupciones, sin que el usuario tenga que reiniciar la sesión manualmente.

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

```kotlin
var complyCubeBuilder = ComplyCubeSdk.Builder(this,
    callback = { result ->
        if (result is Result.Error) {
            if (result.errorCode is ComplyCubeErrorCode.ExpiredToken) {
                // Inserte aquí el código personalizado de renovación del token
            }
        }
    }
)
```

{% endtab %}

{% tab title="Java" %}

```java
ComplyCubeSdk.Builder complyCubeBuilder =
    new ComplyCubeSdk.Builder(this, result -> {
        if (result instanceof Result.Error) {
            if (((Result.Error) result).getErrorCode() == ComplyCubeErrorCode.ExpiredToken.INSTANCE) {
                // Inserte aquí el código personalizado de renovación del token
            }
        }
        return null;
    });
```

{% 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.complycube.com/documentation/sdks/sdks-es/integraciones-moviles/android-sdk/integracion-basada-en-comprobaciones.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.
