> 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-de-workflows.md).

# Integración de workflows

## Descripción general

Esta guía le muestra cómo integrar el **Android SDK** con ComplyCube [flujos de trabajo](/documentation/product-guides/product-guide-es/compliance-studio/workflows.md).

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

## 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 %}

#### **Genera 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 datos, documentos, videos y selfies

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

{% step %}

#### Realizar checks

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/eb4b36b195957d3b8839156147517b0deb83788f" alt=""><figcaption><p>Guía de integración del SDK móvil a través de flujos de trabajo</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 %}

#### Genere 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 %}

#### Inicialice el SDK

Como parte de la inicialización del SDK, debe especificar un [ID de plantilla de flujo de trabajo](https://portal.complycube.com/workflowTemplates). El SDK ejecutará automáticamente la **activa** versión del flujo de trabajo seleccionado.

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

```kotlin
val complyCubeBuilder = ComplyCubeSdk.Builder(this, callback =  { }).apply {
    withWorkflowTemplateId( workflowTemplateId = "WORKFLOW_TEMPLATE_ID" )
}.start(
    ClientAuth(
        token = "SDK_TOKEN",
        clientId = "CLIENT_ID"
    )
)
```

{% endtab %}

{% tab title="Java" %}

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

complycubeFlow.withWorkflowTemplateId("WORKFLOW_TEMPLATE_ID");

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

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

{% step %}

#### Realizar verificación

Una vez que tu cliente inicie el flujo, una [sesión de flujo de trabajo](/documentation/product-guides/product-guide-es/compliance-studio/workflows.md#workflow-session) se crea automáticamente. Esta sesión contiene todos los datos capturados (documentos, imágenes y videos), así como el seguimiento del progreso. Puedes verlos todos a través de la [página de sesiones de flujo de trabajo](https://portal.complycube.com/workflowSessions) en el portal o a través de la API.

Cuando el flujo termina, el SDK activa la `onSuccess` función de devolución de llamada. La devolución de llamada proporciona un `datos` objeto que incluye el `workflowSessionId`. Tu **backend móvil** debe usar este ID para notificar a ComplyCube que el [flujo de trabajo ha finalizado](/documentation/api-reference/core-resources/workflow-sessions/complete-a-workflow-session.md), lo que a su vez ejecuta las comprobaciones de verificación definidas en el flujo de trabajo.

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), recibirás una notificación cuando se complete una sesión de flujo de trabajo.

#### Ejemplo de una solicitud completa de sesión de flujo de trabajo

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

```bash
curl -X POST https://api.complycube.com/v1/workflowSessions/{:wfSessionId}/complete \
     -H 'Authorization: <YOUR_API_KEY>' \
     -H 'Content-Type: application/json'
```

{% endtab %}

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

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

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

const wfSession = await complycube.workflowSession.complete("WORKFLOW_SESSION_ID");
```

{% endtab %}

{% tab title="Python" %}

```python
from complycube import ComplyCubeClient

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

workflow_session = cc_api.workflowsessions.complete('WORKFLOW_SESSION_ID')
```

{% endtab %}

{% tab title="PHP" %}

```php
use ComplyCube\ComplyCubeClient;

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

$workflowSession = $ccapi->workflowSessions()->complete('WORKFLOW_SESSION_ID');
```

{% endtab %}

{% tab title=".NET" %}

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

var wfSessionApi = new WorkflowSessionApi(new ComplyCubeClient("<YOUR_API_KEY>"));

var workflowSession = await wfSessionApi.CompleteAsync("WORKFLOW_SESSION_ID");
```

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

{% step %}

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

Su backend móvil puede recuperar los detalles de la sesión de flujo de trabajo y los resultados de comprobación asociados mediante 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.

Puedes recuperar los detalles de una sesión de flujo de trabajo llamando a la [solicitud para recuperar la sesión de flujo de trabajo](/documentation/api-reference/core-resources/workflow-sessions/get-a-workflow-session.md).

Para recuperar los resultados de la comprobación, puede realizar una [solicitud de obtención de comprobación](/documentation/api-reference/core-resources/checks/get-a-check.md).

**Ejemplo de una solicitud de recuperación de sesión de flujo de trabajo**

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

```bash
curl -X GET https://api.complycube.com/v1/workflowSessions/{:workflowSessionId} \
     -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 wfSession = await complycube.workflowSession.get("WORKFLOW_SESSION_ID");
```

{% endtab %}

{% tab title="Python" %}

```python
from complycube import ComplyCubeClient

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

workflow_session = cc_api.workflowsessions.get('WORKFLOW_SESSION_ID')
```

{% endtab %}

{% tab title="PHP" %}

```php
use ComplyCube\ComplyCubeClient;

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

$workflowSession = $ccapi->workflowSessions()->get('WORKFLOW_SESSION_ID');
```

{% endtab %}

{% tab title=".NET" %}

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

var wfSessionApi = new WorkflowSessionApi(new ComplyCubeClient("<YOUR_API_KEY>"));

var workflowSession = await wfSessionApi.GetAsync("WORKFLOW_SESSION_ID");
```

{% endtab %}
{% endtabs %}

**Ejemplo de una solicitud de recuperación de comprobación**

{% 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 %}

## 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"
    repositories {
        maven { url "https://complycuberepo.jfrog.io/artifactory/cc-gradle-release" }
    }
    ...
}

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:+"
}
```

## Identidad de marca

Puedes personalizar los colores, los logotipos y otros elementos de marca a través de la [página de configuración de la marca](https://portal.complycube.com/settings/branding), si está disponible en tu plan.

## 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 una sesión de verificación, debe implementar el **éxito**, **cancelado**, y **error** callbacks.

Al completarse correctamente (`onSuccess`), puede activar una [solicitudes de finalización de la sesión de flujo de trabajo](/documentation/api-reference/core-resources/workflow-sessions/complete-a-workflow-session.md) desde su backend usando el ID de sesión de flujo de trabajo devuelto en el objeto de resultado.

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:
                    El parámetro 'results' contendrá: 
                      - "workflowSessionId": "xxxxx"
                */
                }
                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:
        El parámetro 'results' contendrá: 
          - "workflowSessionId": "xxxxx"
     */
    } 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-de-workflows.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.
