> 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/sdk-de-react-native/integracion-de-workflows.md).

# Integración de workflows

## Descripción general

Esta guía le muestra cómo integrar el **SDK de React Native** 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-react-native-sdk).<br>

{% stepper %}
{% step %}

#### Instale el SDK

{% tabs %}
{% tab title="React Native" %}

1. Instala la biblioteca de React Native ejecutando:

```bash
npm i -s @complycube/react-native
```

2. Completa los pasos en las **iOS** y **Android** pestañas.

{% hint style="danger" %}

#### Integración de Sentry

Si estás integrando Sentry en tu proyecto de React Native, podrías encontrarte con el siguiente error de compilación:

```javascript
No se puede encontrar el archivo 'SentryDefines.h'.
```

Este problema ocurre debido a una incompatibilidad de versiones entre el paquete Sentry React Native y el SDK nativo de Sentry.

Para resolver este error (a partir de **@sentry/react-native v5.31.0** y **Sentry para iOS v8.36.0**), actualiza las sentencias de importación en tu código.

En `SentrySdkInfo.h` y `SentryInternalSerializable.h`, sustituye:

```javascript
// Sustituye
#import "SentryDefines.h"

// Por
#import <Sentry/SentryDefines.h>
```

{% endhint %}
{% endtab %}

{% tab title="iOS" %}

1. Antes de usar el SDK de ComplyCube, instale el **CocoaPods** plugin ejecutando el siguiente comando en tu terminal:<br>

   ```bash
   sudo gem install cocoapods
   ```

2. Añade repositorios de plugins e instala el pod usando tu `Podfile`:<br>

   ```ruby
   source 'https://github.com/CocoaPods/Specs.git'
   …
   platform :iOS, ’13.0’

   target ‘YourApp’ do
       …
     pod 'ComplyCubeMobileSDK'
   end

   post_install do |installer|
       installer.pods_project.targets.each do |target|
           target.build_configurations.each do |build_configuration|
               build_configuration.build_settings['ENABLE_BITCODE'] = 'NO'
               build_configuration.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
               build_configuration.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.1'
               build_configuration.build_settings['ARCHS'] = ['$(ARCHS_STANDARD)', 'x86_64']
               build_configuration.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = ['arm64', 'arm64e', 'armv7', 'armv7s']
               build_configuration.build_settings['GENERATE_INFOPLIST_FILE'] = 'YES'
           end
       end
   end
   ```

\
**Permisos de la aplicación**

Nuestro SDK utiliza la cámara y el micrófono del dispositivo para la captura. Debe añadir las siguientes claves a su aplicación `Info.plist` archivo.

1. `NSCameraUsageDescription`

```xml
<key>NSCameraUsageDescription</key>
<string>Se utiliza para capturar biometría facial y documentos</string>
```

2. `NSMicrophoneUsageDescription`

```xml
<key>NSMicrophoneUsageDescription</key>
<string>Se utiliza para capturar biometría de vídeo</string>
```

{% endtab %}

{% tab title="Android" %}
Nuestro SDK requiere los repositorios siguientes.

```java
repositories {
  mavenCentral()
}

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

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

#### 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.

```jsx
import { ComplyCube } from "@complycube/react-native";
// ...

const settings = {
  clientID: "<CLIENT_ID>",
  clientToken: "<CLIENT_TOKEN>",
  workflowTemplateId: "<WORKFLOW_TEMPLATE_ID>",
  // ... otros ajustes
};

return (
  <View style={styles.container}>
    <ComplyCube settings={settings} />
  </View>
);
```

{% endstep %}

{% step %}

#### Realizar checks

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

{% tabs %}
{% tab title="iOS" %}
{% hint style="info" %}
Para usar esta función, tu aplicación debe tener la **`lectura de etiquetas de Comunicación de Campo Cercano`** habilitada. Para añadir esta capacidad a tu aplicación, consulta [la guía de Apple aquí](https://help.apple.com/xcode/mac/current/#/dev88ff319e7).
{% endhint %}

1. Instala el **CocoaPods Artifactory** plugin ejecutando el siguiente comando en tu terminal:<br>

   ```bash
   gem install cocoapods-art
   ```

2. Para añadir la biblioteca, copia las credenciales de tu repositorio en un `.netrc` archivo en tu directorio de inicio y configura el repositorio:<br>

   <pre class="language-bash" data-overflow="wrap"><code class="lang-bash">pod repo-art add cc-cocoapods-release-local "https://complycuberepo.jfrog.io/artifactory/api/pods/cc-cocoapods-release-local"
   </code></pre>

   \
   Recuerda obtener tus credenciales de **JFrog** usando el **Configurar** botón [aquí](https://complycuberepo.jfrog.io/ui/repos/tree/General/cc-cocoapods-release-local).<br>

3. Añade repositorios de plugins e instala el pod usando tu `Podfile`:<br>

   ```ruby
    plugin 'cocoapods-art', :sources => [
      'cc-cocoapods-release-local',
      'trunk'
    ]
    ...
    platform :ios, '13.0' # O superior

    target 'YourApp' do
      use_frameworks!
      use_modular_headers!
      ...
      pod 'ComplyCubeMobileSDK', '2.0.x-nfc'
      ...
    en
   ```

4. Debes añadir las siguientes claves a tu aplicación `Info.plist` archivo:<br>

   ```xml
   <key>NFCReaderUsageDescription</key>
   <string>Requerido para leer documentos con NFC habilitado</string>
   ```

5. Para leer correctamente las etiquetas NFC, debes añadir las siguientes entradas al target de tu aplicación `Info.plist` archivo:<br>

   ```xml
   <key>com.apple.developer.nfc.readersession.felica.systemcodes</key>
   <array>
     <string>12FC</string>
   </array>
   <key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
   <array>
     <string>A0000002471001</string>
     <string>A0000002472001</string>
     <string>00000000000000</string>
     <string>D2760000850101</string>
     <string>E80704007F00070302</string>
     <string>A000000167455349474E</string>
     <string>A00000045645444C2D3031</string>
   </array>
   ```

6. Añade lo siguiente en tu `Runner.entitlements` archivo:<br>

   ```xml
   <key>com.apple.developer.nfc.readersession.formats</key>
   <array><string>TAG</string></array>
   ```

7. Para habilitar NFC al compilar tu app de iOS, pasa la `USE_CCNFC` variable de entorno durante la compilación:<br>

   ```bash
   USE_CCNFC=true flutter build ios
   ```

   \
   Para mantener esto habilitado en todas las compilaciones de iOS, añade la siguiente línea cerca de la parte superior de tu `ios/Podfile`:<br>

   ```ruby
   ENV['USE_CCNFC'] ||= 'true'
   ```

{% endtab %}

{% tab title="Android" %}

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
USE_NFC=true
artifactory_contextUrl=https://complycuberepo.jfrog.io/artifactory/cc-gradle-release
artifactory_user=<YOUR_USERNAME>
artifactory_password=<YOUR_PASSWORD>
```

> Reemplace <**YOUR\_USERNAME**> y <**YOUR\_PASSWORD**> con sus credenciales de ComplyCube Artifactory. Si no tiene acceso, póngase en contacto con el Soporte de ComplyCube para solicitar credenciales.

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

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

```javascript
repositories {
    google()
    mavenCentral()
    maven {
        url project.findProperty("artifactory_contextUrl")
        credentials {
            username = project.findProperty("artifactory_user")
            password = project.findProperty("artifactory_password")
        }
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```python
repositories {
    google()
    mavenCentral()
    maven {
        url = uri(project.findProperty("artifactory_contextUrl") as String)
        credentials {
            username = project.findProperty("artifactory_user") as String?
            password = project.findProperty("artifactory_password") as String?
        }
    }
}
```

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

## 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.

```jsx
function onSuccess(results){
  /*
    Gestión de resultados satisfactorios:
    El parámetro 'results' contendrá: 
      - "workflowSessionId": "xxxxx"
  */
  console.log(results);
}

function onCancelled(){
  console.log("El usuario canceló");
}

function onError(error){
  console.log(error);
}

return(<View>
    <ComplyCube 
      settings={settings}
      onSuccess={onSuccess}
      onCancel={onCancelled}
      onError={onError}
       />
  </View>
)
```

<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 tu propio seguimiento, define una función y aplícala usando el `eventHandler` propiedad en tus `ajustes`:

```jsx
function myCustomEventHandler(event){
  // Inserta aquí código personalizado de seguimiento de usuarios
  console.log(event.code);
  console.log(event.message);
}

const settings = {
  eventHandler: myCustomEventHandler,
  // ... otros ajustes
}
```

<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.

```jsx
function myCustomExpiryHandler(){
  // Inserte aquí el código personalizado de renovación del token
}

const settings = {
  tokenExpiryHandler: myCustomExpiryHandler,
  // ... otros ajustes
}
```


---

# 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/sdk-de-react-native/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.
