# QI Tech — Risk Solutions › Reconhecimento facial

Documentação da QI Tech em texto corrido, para colar em um LLM.
Fonte: https://docs.qitech.com.br
31 página(s).

Índice:
- Coletando os Resultados (/documentation/caas/face_recognition/android/collecting_response)
- Introdução (/documentation/caas/face_recognition/android/introduction)
- Integração nativa (/documentation/caas/face_recognition/android/native_java)
- Autenticação (/documentation/caas/face_recognition/api/authentication)
- Registro de rosto (1:1) (/documentation/caas/face_recognition/api/face_registration)
- Status HTTP (/documentation/caas/face_recognition/api/http_status)
- Imagem (/documentation/caas/face_recognition/api/image)
- Introdução (/documentation/caas/face_recognition/api/introduction)
- Padrões (/documentation/caas/face_recognition/api/standards)
- Coletando os Retornos (/documentation/caas/face_recognition/flutter/collecting_response)
- Compatibilidade (/documentation/caas/face_recognition/flutter/compatibility)
- Implementação (/documentation/caas/face_recognition/flutter/example)
- O objeto FaceReconOptions (/documentation/caas/face_recognition/flutter/face_recon_options)
- Instalação (/documentation/caas/face_recognition/flutter/installation)
- Introdução (/documentation/caas/face_recognition/flutter/introduction)
- Coletando os Retornos do SDK (/documentation/caas/face_recognition/ios/collecting_response)
- QITechIosFaceRecognitionConfiguration (/documentation/caas/face_recognition/ios/configuration)
- Introdução (/documentation/caas/face_recognition/ios/introduction)
- Importando o SDK (/documentation/caas/face_recognition/ios/native_swift)
- Coletando os Retornos (/documentation/caas/face_recognition/react_native/collecting_response)
- Compatibilidade (/documentation/caas/face_recognition/react_native/compatibility)
- Implementação (/documentation/caas/face_recognition/react_native/example)
- O objeto FaceReconOptions (/documentation/caas/face_recognition/react_native/face_recon_options)
- Instalação (/documentation/caas/face_recognition/react_native/installation)
- Introdução (/documentation/caas/face_recognition/react_native/introduction)
- Coletando os Retornos do SDK (/documentation/caas/face_recognition/web/collecting_response)
- Implementação (/documentation/caas/face_recognition/web/example)
- O construtor QITechWebFaceRecon.WebFaceRecon() (/documentation/caas/face_recognition/web/example_zaigwebfacerecon)
- Importando a biblioteca (/documentation/caas/face_recognition/web/import)
- Introdução (/documentation/caas/face_recognition/web/introduction)
- Registro de Rosto e Validação 1:1 (/documentation/caas/face_recognition/web/registration_and_validation)

---

# Coletando os Resultados

URL: /documentation/caas/face_recognition/android/collecting_response

Para obter o objeto **FaceReconResponse**, que contém os resultados das capturas obtidas pelo SDK, incluindo os identificadores das imagens enviadas no sistema QI Tech, sobrescreva o método *onActivityResult* na mesma activity que você iniciou a **FaceReconActivity**:

```java
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE) {
            if (resultCode == RESULT_OK && data != null) {
                faceReconResponse = data.getParcelableExtra("FaceReconResponse");
                image_key = faceReconResponse.image_key;
                device_scan_session_id = faceReconResponse.device_scan_session_id;
                Log.i(TAG_LIVENESS, "FACE RECON RESPONSE: " + faceReconResponse.image_key);
            }
            else if (resultCode == RESULT_CANCELED && data != null) {
                faceReconResponse = data.getParcelableExtra("FaceReconResponse");
                Log.i(TAG_LIVENESS, "FACE RECON RESPONSE: " + faceReconResponse.status_code + " - " + faceReconResponse.reason + " - " + faceReconResponse.description);
            }
        }
    }
```

## Descrição dos Atributos do Objeto FaceReconResponse

:::info Aviso: 
Integração com Device Scan A partir da versão 5.2.0, o serviço de Face Recognition passa a realizar automaticamente uma chamada interna ao Device Scan. Com isso, o retorno de sucesso incluirá o campo `device_scan_session_id`. Esta chave identifica a sessão de scan de dispositivo realizada internamente e pode ser utilizada de forma integrada em outros serviços do ecossistema QI Tech. 
:::

Atributo | Descrição | Resultado | Versões
--------- | --------- | --------- | ---------
image_key | Chave de identificação da imagem fornecida que pode ser utilizada em qualquer outro serviço do sistema QI Tech. | **RESULT_OK** | **Todas**
device_scan_session_id | Chave de identificação da sessão de scan de dispositivo realizada internamente que pode ser utilizada em qualquer outro serviço do sistema QI Tech. | **RESULT_OK** |  **5.2.0+**
status_code | Status code da requisição. | **RESULT_CANCELED** | **5.0.0+**
reason | Identificador do erro | **RESULT_CANCELED** | **5.0.0+**
description | Descrição do erro. | **RESULT_CANCELED** | **5.0.0+**

## Estrutura de Erro (SDK 5.0.0+)

:::danger Aviso Importante! 
A partir da versão **5.0.0**, a estrutura de erros foi reformulada para fornecer informações mais detalhadas e diagnósticas.
:::

### Exemplo: InvalidToken

```java
{
   status_code = 401
    reason = "INVALID_TOKEN"
    description = "Authentication token expired or invalid"
}
```
### Exemplo: UserCanceled

```java
{
    status_code = 0
    reason = "USER_CANCELED"
    description = "User pressed the back button."
}
```

## Versões Anteriores

```java
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        FaceRecognition.RequestResponseObject result;
        if (requestCode == REQUEST_CODE){
            if (resultCode == RESULT_OK && data != null){
                faceReconResponse = data.getParcelableExtra("FaceReconResponse");
            }
        }
    }
```

---

# Introdução

URL: /documentation/caas/face_recognition/android/introduction

Bem-vindo ao SDK Android de Reconhecimento Facial da QI Tech. Este SDK realiza a captura da face e o seu envio para a API de Face Recognition da QI Tech . Você pode utilizá-lo para capturar uma imagem do rosto de um cliente por meio do seu aplicativo e referenciá-la por meio de uma chave nos demais produtos do sistema QI Tech.

## Problemas?

Nós não somos uma companhia que se esconde atrás de uma API! Entre em contato com o nosso [suporte](mailto:suporte.caas@qitech.com.br) e nós responderemos o mais rápido possível. Fique à vontade para nos ligar caso deseje uma resposta rápida!

### Adoramos Feedback

Mesmo que você já tenha resolvido o seu problema ou que ele seja muito simples (Até mesmo um typo ou uma organização inadequada que você já entendeu), envie-nos um e-mail, assim nós tornamos a documentação cada vez mais prática e a próxima pessoa não vai precisar sofrer as dores que você sofreu!

:::danger Aviso Importante!
Não devem ser usados dados reais de pessoas físicas e/ou jurídicas nos ambientes de Sandbox da QI Tech.  
:::

---

# Integração nativa

URL: /documentation/caas/face_recognition/android/native_java

Para importar nossas SDKs, é necessário realizar alteração no _build.gradle_ de Projeto e de Aplicativo.

## Adicionando ao Projeto

Adicione o endereço de nosso repositório maven no _build.gradle_ do projeto (no Android Studio este arquivo aparece como: **"Project: \{nome_do_projeto\}"**), conforme exemplo abaixo.

```java
maven { url 'https://sdks.qitech.com.br/' }
```

## Adicionando ao Aplicativo

Após isso, adicione a biblioteca que você pretende importar em seu build.gradle do app (no Android Studio este arquivo aparece como: **"Module: \{nome_do_projeto\}.app"**), incluindo a dependência apresentada abaixo.

```java
dependencies {
    implementation 'com.qitech.android:facerecon:v7.1.0'
}
```

:::warning
Desde **abril de 2025**, novas políticas da Google Play requerem **Android API Level 35** para que aplicativos possam ser publicados
ou atualizados na Google Play Store. Por isso recomendamos fortemente que utilize **targetSdkVersion na versão 35** pelo menos.
:::

:::info
A utilização de **targetSdkVersion 35** implica na utilização do **compileSdkVersion 35**, o que desencadeia alguns **requisitos mínimos** para ferramentas
do ecossistema do Android:
* compileSdkVersion 35 --> AGP 8.6.0
* AGP 8.6.0 --> Gradle 8.7
* AGP 8.6.0 --> Java 17 (JDK 17)
* AGP 8.6.0 --> Kotlin 2+
:::

## Iniciando o SDK

:::danger Aviso Importante!
A partir da versão 5.0.0, o sistema de autenticação foi atualizado para usar **clientSessionKey** em vez de **mobileToken**. Além disso, foram adicionadas novas opções de configuração para telas de feedback.
:::

### Obtendo o Client Session Key

Antes de configurar o SDK, você deve gerar um **clientSessionKey** temporário através de uma requisição server-to-server para a nossa API de face recognition.

### Endpoint

| Ambiente | URL |
|----------|-----|
| **Sandbox** | `https://api.sandbox.zaig.com.br/face_recognition/client_session` |
| **Produção** | `https://api.zaig.com.br/face_recognition/client_session` |

### Requisição

**Method:** `POST`

**Headers:**
```json
{
  "Authorization": "YOUR_FACE_RECON_API_KEY"
}
```

**Body (Opcional, mas recomendado):**
```json
{
  "user_id": "unique_user_identifier" // Se disponível, utilize o CPF do usuário!
}
```

> **Importante:** O campo `user_id` é **altamente recomendado** para medidas de segurança e antifraude. Use um identificador único do usuário da sua aplicação.

### Resposta

A resposta bem-sucedida conterá o `client_session_key` que deve ser passado para a configuração do SDK.

```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

Para incorporar o SDK ao seu aplicativo você deve realizar a configuração do seu aplicativo de captura personalizado através de um componente Builder e submetê-lo como parâmetro via Intent Extra para a FaceReconActivity.

### Exemplo de inicialização do SDK
```java
  Intent intent = new Intent(getApplicationContext(), FaceReconActivity.class);

  var onboardingTextConfiguration = new OnboardingTextConfiguration(
        "Conselhos relevantes",
        "Esteja com o rosto visível",
        "Encaixe seu rosto no oval",
        "Retire acessórios que cubram o rosto"
  );

  FaceRecognition mFaceRecognition = new FaceRecognition.Builder(clientSessionKey)
        .setSessionId("SESSION_ID")
        .setDocumentNumber("111.111.111-11")
        .setFontColor("#FFFFFF")
        .setBackgroundColor("#000000")
        .setFontFamily(FaceRecognition.FontFamily.futura)
        .showIntroductionScreens(true)
        .setShowSuccessScreen(true)
        .setShowInvalidTokenScreen(false)
        .setOnboardingTextConfiguration(onboardingTextConfiguration)
        .audioConfiguration(AudioConfiguration.enable)
        .setLogLevel(FaceRecognition.LogLevel.debug)
        .build();

  intent.putExtra("settings", mFaceRecognition);
  startActivityForResult(intent, REQUEST_CODE);
```

**Versões anteriores à v6.0.0**
```java
  Intent intent = new Intent(getApplicationContext(), FaceReconActivity.class);

  VisualConfiguration visualConfiguration = new VisualConfiguration()
          .setOnboardingDrawable(R.drawable.introscreen,500);

  TextConfiguration textConfiguration = new TextConfiguration()
          .setCustomText(TextConfiguration.CustomLabel.onboardingTitle, "Para tirar uma boa foto:")
          .setCustomText(TextConfiguration.CustomLabel.onboardingFirstLabel, "- Vá para um local iluminado")
          .setCustomText(TextConfiguration.CustomLabel.onboardingSecondLabel, "- Retire adereços e mostre bem o rosto")
          .setCustomText(TextConfiguration.CustomLabel.onboardingThirdLabel, "- Insira seu rosto na moldura, aguardando que fique verde para realizar a captura");

  FaceRecognition mFaceRecognition = new FaceRecognition.Builder(clientSessionKey)
          .showIntroductionScreens(true)
          .setVisualConfiguration(visualConfiguration)
          .setTextConfiguration(textConfiguration)
          .setBackgroundColor("#000000")
          .setFontColor("#FFFFFF")
          .setFontFamily(FaceRecognition.FontFamily.futura)
          .setSessionId("SESSION_ID")
          .setLogLevel(FaceRecognition.LogLevel.debug)
          .setShowSuccessScreen(false)
          .build();
  intent.putExtra("settings", mFaceRecognition);
  startActivityForResult(intent, REQUEST_CODE);
```

## FaceRecognition.Builder
| Parâmetro | Função | Obrigatório |
|------------|--------------|--------------|
|clientSessionKey |Chave do cliente que identifica que os dados coletados são provenientes do seu aplicativo. Obtida através de requisição à API da Face Recognition|Sim.|
|.setSandboxEnvironment()|Caso este parâmetro seja utilizado no construtor, a biblioteca será configurada para enviar os dados ao ambiente de sandbox. Caso ausente, as requisições são enviadas para o ambiente production.|Não.|
|.showIntroductionScreens(Boolean showIntroductionScreens)|Quando "false" desativa as telas de introdução à coleta da foto que aparecem para o usuário.|Não. O padrão é "true".|
|.setShowSuccessScreen(Boolean showSuccessScreen)|Quando "false" desativa a tela de sucesso após a coleta da foto.|Não. O padrão é "true".|
|.setShowInvalidTokenScreen(Boolean showSuccessScreen)|Quando "false" desativa a tela de falha de autenticação.|Não. O padrão é "true".|
|.setBackgroundColor(String backgroundColor)|Permite a configuração da cor de background das activities do SDK.|Não. O padrão é "#ffffff".|
|.setFontColor(String fontColor)|Permite a configuração da cor da fonte e dos ícones das activities do SDK.|Não. O padrão é "#000000".|
| .setFontFamily(FontFamily fontFamily)| Permite a configuração da fonte das activities do SDK.| Não. Caso não seja informada o padrão é FontFamily.open_sans. Fontes disponíveis: FontFamily.open_sans, FontFamily.futura, FontFamily.verdana, FontFamily.roboto, FontFamily.poppins e FontFamily.helvetica.|Não.|
|.setOnboardingTextConfiguration(OnboardingTextConfiguration onboardingTextConfiguration) | Permite a customização das instruções na tela de introdução. | Não. |
|.audioConfiguration(AudioConfiguration audioConfiguration)|Configura o guiamento por voz do SDK, que narra as instruções de captura em tempo real. As configurações aceitas são _AudioConfiguration.enable_, que exibe o botão de ligar/desligar áudio com a narração iniciando desligada; _AudioConfiguration.disable_, que desativa a narração e oculta o botão; e _AudioConfiguration.accessibility_, que exibe o botão com a narração iniciando ligada quando o dispositivo possui recursos de acessibilidade ativos. Com o TalkBack ativo, as instruções completas são entregues pelo próprio leitor de telas.|Não. O padrão é _AudioConfiguration.disable_.|
|.setSessionId(String sessionId)| Utilizado para definir a chave que identifica a sessão iniciada no SDK. É usada para rastrear todo fluxo percorrido pelo usuário na execução da FaceRecon através de logs. Este campo aceita até 255 caracteres. |Não.|
|.setLogLevel(FaceRecognition.LogLevel logLevel)| Utilizado para customizar o nível de verbosidade dos logs do SDK. Níveis disponíveis: LogLevel.debug, LogLevel.info, LogLevel.warn, LogLevel.error e LogLevel.trace. O padrão é LogLevel.debug. |Não.|
|.setDocumentNumber(String documentNumber)| Utilizado para definir o número do documento do usuário. Este campo aceita 14 caracteres. | Para Identificação utilizada internamente para anti-fraude e segurança. |

**Versões anteriores à v6.0.0**
| Parâmetro | Função | Obrigatório |
|------------|--------------|--------------|
|clientSessionKey |Chave do cliente que identifica que os dados coletados são provenientes do seu aplicativo. Obtida através de requisição à API da Face Recognition|Sim.|
|.setSandboxEnvironment()|Caso este parâmetro seja utilizado no construtor, a biblioteca será configurada para enviar os dados ao ambiente de sandbox. Caso ausente, as requisições são enviadas para o ambiente production.|Não.|
|.showIntroductionScreens(Boolean showIntroductionScreens)|Quando "false" desativa as telas de introdução à coleta da foto que aparecem para o usuário.|Não. O padrão é "true".|
|.setShowSuccessScreen(Boolean showSuccessScreen)|Quando "false" desativa a tela de sucesso após a coleta da foto.|Não. O padrão é "true".|
|.setShowInvalidTokenScreen(Boolean showSuccessScreen)|Quando "false" desativa a tela de falha de autenticação.|Não. O padrão é "true".|
|.setBackgroundColor(String backgroundColor)|Permite a configuração da cor de background das activities do SDK.|Não. O padrão é "#ffffff".|
|.setFontColor(String fontColor)|Permite a configuração da cor da fonte e dos ícones das activities do SDK.|Não. O padrão é "#000000".|
| .setFontFamily(FontFamily fontFamily)| Permite a configuração da fonte das activities do SDK.| Não. Caso não seja informada o padrão é FontFamily.open_sans. Fontes disponíveis: FontFamily.open_sans, FontFamily.futura, FontFamily.verdana, FontFamily.roboto, FontFamily.poppins e FontFamily.helvetica.|Não.|
|.activeFaceLiveness(Boolean activeFaceLiveness)|Indica se o SDK deve realizar um procedimento de captura de selfie do usuário ou de prova de vida ativa. |Não. O padrão é *false*.|
|.audioConfiguration(AudioConfiguration audioConfiguration)|Configura o guiamento por voz do SDK, que narra as instruções de captura em tempo real. As configurações aceitas são _AudioConfiguration.enable_, que exibe o botão de ligar/desligar áudio com a narração iniciando desligada; _AudioConfiguration.disable_, que desativa a narração e oculta o botão; e _AudioConfiguration.accessibility_, que exibe o botão com a narração iniciando ligada quando o dispositivo possui recursos de acessibilidade ativos. Com o TalkBack ativo, as instruções completas são entregues pelo próprio leitor de telas.|Não. O padrão é _AudioConfiguration.disable_.|
|.setVisualConfiguration(VisualConfiguration visualConfiguration)|Utilizado para customizar as imagens mostradas para o usuário ao longo da execução do SDK.|Não.|
|.setTextConfiguration(TextConfiguration textConfiguration)|Utilizado para customizar os textos da tela introdutória de onboarding mostradas para o usuário ao longo da execução do SDK.|Não.|
|.setSessionId(String sessionId)| Utilizado para definir a chave que identifica a sessão iniciada no SDK. É usada para rastrear todo fluxo percorrido pelo usuário na execução da FaceRecon através de logs. Este campo aceita até 255 caracteres. |Não.|
|.setLogLevel(FaceRecognition.LogLevel logLevel)| Utilizado para customizar o nível de verbosidade dos logs do SDK. Níveis disponíveis: LogLevel.debug, LogLevel.info, LogLevel.warn, LogLevel.error e LogLevel.trace. O padrão é LogLevel.debug. |Não.|
|.setDocumentNumber(String documentNumber)| Utilizado para definir o número do documento do usuário. Este campo aceita 14 caracteres. |Apenas para as chamadas que utilizem a validação 1:1 em algum momento. |
|.setValidation(Boolean validation)| Utilizado para definir se o SDK deve ou não realizar a validação 1:1 com a selfie do usuário. Na primeira sessão do usuário esta flag deve estar, **obrigatoriamente**, false. Esta função necessita do método setDocumentNumber preenchido.  |Não. O padrão é *false*.|

## O Objeto VisualConfiguration
:::warning
__DEPRECADO__ A PARTIR DA **v6.0.0**!
:::

| Parâmetro                                                             | Função                                                                                                                                                                                                                                        | Obrigatório             |
| --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- |
| .setOnboardingDrawable(int onboarding_drawable, int onboarding_width) | Utilizado para configurar a imagem mostrada para o usuário na tela de onboarding do SDK. O parâmetro _onboarding_drawable_ deve referenciar o id da imagem a ser mostrada e _onboarding_width_ é o tamanho desejado de exibição desta imagem. | Não.                    |
| .setButtonBorderSize(int border_size)                                 | Utilizado para configurar a largura de borda dos botões do SDK.                                                                                                                                                                               | Não. O padrão é _1_.    |
| .setButtonShadow(boolean button_shadow)                               | Quando setado para _false_ remove o efeito de sombra, padrão no android, utilizado pelos botões do SDK.                                                                                                                                       | Não. O padrão é _true_. |

## O Objeto TextConfiguration
:::warning
__DEPRECADO__ A PARTIR DA **v6.0.0**!
:::

| Parâmetro                                      | Função                                                                                    | Obrigatório |
| ---------------------------------------------- | ----------------------------------------------------------------------------------------- | ----------- |
| .setCustomText(CustomLabel label, String text) | Utilizado para configurar os textos mostrados para o usuário na tela de onboarding do SDK | Não.        |

---

# Autenticação

URL: /documentation/caas/face_recognition/api/authentication

:::danger Aviso Importante!
A partir da versão 5.0.0 das SDKs de iOS e Android e a versão 3.0.0 do SDK de Web, o sistema de autenticação foi atualizado para usar clientSessionKey em vez de mobileToken.
:::

Utilizamos uma API Key para permitir acesso à nossa API. Ela provavelmente já foi enviada por e-mail para você. Caso ainda não tenha recebido a sua chave, envie um e-mail para suporte.caas@qitech.com.br .

## Client Session Key

Antes de configurar o SDK, você deve gerar um clientSessionKey temporário através de uma requisição server-to-server para a nossa API.

### Gerar Client Session Key

```bash
curl -X POST "https://api.zaig.com.br/face_recognition/client_session" \
     -H "Authorization: EXAMPLE_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{ "user_id": "unique_user_identifier" }'
```

**Endpoints**

| Ambiente | URL |
|----------|-----|
| Sandbox | https://api.sandbox.zaig.com.br/face_recognition/client_session |
| Produção | https://api.zaig.com.br/face_recognition/client_session |

**Detalhes da Requisição**

| Campo | Tipo | Obrigatório | Descrição|
|----------|----------|----------|----------|
| user_id | string | Não | Identificador único do usuário da sua aplicação (ex: CPF, RG, etc) |

O campo `user_id` no corpo da requisição é altamente recomendado para medidas de segurança e antifraude.

**Request Body**
```json
{
  "user_id": "unique_user_identifier"
}
```

**Response Body**

A resposta bem-sucedida conterá o `client_session_key`.
```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

:::info Atenção
Você deve substituir `EXAMPLE_API_KEY` pela API Key recebida do suporte.
:::

---

# Registro de rosto (1:1)

URL: /documentation/caas/face_recognition/api/face_registration

Para realizar um **registro de rosto** (para posterior validação 1:1), é necessário utilizar os **endpoints específicos** da API de Face Recognition descritos nesta página.

## Endpoints disponíveis

Os recursos de registro de rosto estão expostos nas seguintes rotas:

| Método | Endpoint | Descrição |
|--------|----------|-----------|
| POST | `/face_recognition/registration` | Cria um novo registro de rosto |
| GET | `/face_recognition/registration/{registration_key}` | Recupera registro pela chave |
| GET | `/face_recognition/registration/document_number/{document_number}` | Recupera registro pelo número do documento |

**URL base (produção):** `https://api.caas.qitech.app`  
**URL base (sandbox):** `https://api.sandbox.caas.qitech.app`

---

## Criação de um registro (POST)

Para cadastrar o rosto de um cliente, envie uma requisição **POST** para:

`https://api.caas.qitech.app/face_recognition/registration`

O corpo da requisição deve conter o **número do documento** e a imagem do rosto, de uma das duas formas abaixo.

### Opção 1: imagem via `image_key` (extraída da SDK)

Utilize o **image_key** retornado pela SDK após a captura do rosto.

Request Body – image_key

```json
{
    "document_number": "DOCUMENT_NUMBER",
    "image_key": "<IMAGE_KEY_FROM_SDK>"
}
```

### Opção 2: imagem em Base64

Envie a imagem diretamente em Base64 (sem cabeçalhos ou metadados adicionais).

Request Body – image (Base64)

```json
{
    "document_number": "DOCUMENT_NUMBER",
    "image": "<IMAGE_BASE64>"
}
```

### Campos do request

nome | tipo | descrição
:----: | :----: | ---------
document_number | string | Número do documento (ex.: CPF) do cliente
image_key | string | Chave da imagem retornada pela SDK (UUID). Use **ou** `image_key` **ou** `image`
image | string | Imagem do rosto em Base64. Use **ou** `image` **ou** `image_key`

:::info
É obrigatório enviar **apenas um** dos campos de imagem: `image_key` **ou** `image`. Não envie os dois no mesmo request.
:::

Após o envio com sucesso, a API retorna apenas a chave do registro de rosto:

Response Body

```json
{
    "registration_key": "chave_do_registro_do_rosto"
}
```

---

## Recuperação de registro por chave (GET)

Para obter a chave de um registro pela sua chave única:

`https://api.caas.qitech.app/face_recognition/registration/{registration_key}`

Substitua `{registration_key}` pelo identificador retornado na criação do registro.

**Response Body:**

```json
{
    "registration_key": "chave_do_registro_do_rosto"
}
```

---

## Recuperação de registro por documento (GET)

Para obter a chave de um registro pelo número do documento:

`https://api.caas.qitech.app/face_recognition/registration/document_number/{document_number}`

Substitua `{document_number}` pelo número do documento do cliente (ex.: CPF).

**Response Body:**

```json
{
    "registration_key": "chave_do_registro_do_rosto"
}
```

---

---

# Status HTTP

URL: /documentation/caas/face_recognition/api/http_status

Todas as APIs da QI Tech utilizam a seguinte padronização nos status HTTP de retorno, de acordo com o RFC 7231 :

Status HTTP | Significado | Descrição
---------- | ------- | ---------------------------------
400 | Bad Request | A requisição enviada possui algum erro de formatação. Na maioria dos casos, retornamos no corpo da mensagem uma explicação de onde está o erro.
401 | Unauthorized | Houve algum problema na autenticação, verifique se a API Key está correta e no header correto, de acordo com a seção Autenticação .
403 | Forbidden | O endpoint acessado é de uso interno e não está disponível para esta API Key.
404 | Not Found | O dado requisitado não foi encontrado usando a chave utilizada. Este status também é retornado quando um endpoint inválido é requisitado.
405 | Method Not Allowed | O método HTTP utilizado não se aplica ao endpoint utilizado.
406 | Not Acceptable | Os dados enviados no corpo da requisição são inválidos. Em geral, isso significa que os dados enviados não são um JSON válido.
409 | Conflict | O id da requisição corresponde a um id já processado anteriormente. Este status é retornado no caso de requisições duplicadas enviadas ao servidor.
500 | Internal Server Error | Tivemos um problema para processar esta requisição, ao encontrarmos esse erro nossos especialistas são automaticamente notificados e iniciam a análise e solução imediatamente.
503 | Service Unavailable | Você se deparou com uma indisponibilidade, planejada ou não, de infraestrutura dos nossos servidores.

---

# Imagem

URL: /documentation/caas/face_recognition/api/image

O envio de uma foto de rosto é mandatório para a utilização de nossa API de reconhecimento facial. Visando garantir uma maior confiabilidade das análises executadas, é necessário que o cliente siga algumas regras na hora de tirar a foto:

* A foto deve conter apenas um rosto;
* Todo o rosto deve estar visível na foto;
* O rosto deve ocupar ao menos 15% da area da foto;
* O rosto deve estar encarando a câmera e paralelo a ela;
* O rosto deve estar com os olhos abertos;
* O rosto deve estar com a boca fechada;
* O rosto deve possuir expressão neutra e sem sorrisos;
* O rosto não deve estar coberto por nenhum tipo de acessório (chapéus, óculos ou máscaras).

Além disso, somente imagens .jpeg e .png com tamanho máximo de 3MB serão aceitas.

## Envio de arquivos

Request Body

```json
{
    "image": "base64_image_code"
}
```

Response Body

```json
{ 
    "image_key": "f4b5337a-7b50-406e-8c8e-7d0e77b5aa02",
    "file_size": 47407,
    "width_px": 0,
    "height_px": 0,
    "created_at": "2020-07-29T18:40:57Z"
}
```

Em casos que seja necessário o envio de uma imagem sem a execução imediata das rotinas de cadastro ou validação facial, um objeto JSON contendo o Base64 da imagem deve ser enviado. 
Para tal deve-se enviar uma requisição do tipo **POST** para o endpoint:

`https://api.caas.qitech.app/face_recognition/image`

Uma vez enviada, a imagem será submetida a testes de qualidade e, caso aprovada, será retornado um JSON contendo a chave de acesso à imagem. Essa chave deverá ser usada para referenciar a foto durante o cadastro ou validação facial.

:::info **Atenção**

Deve ser enviado apenas o código Base64 correspondente a imagem.
:::

## Validação de qualidade da imagem

Response Body: Caso de imagem inválida

```json
{
    "title": "image_quality",
    "description": "This image was not approved in quality assessment. The face is too close to image edges.",
    "image_status": "not_center"
}
```

Ao realizar um post no endpoint de imagem, caso a imagem não seja suficiente para validação, um HTTP Status Code 400 será retornado.

O valor do campo *description* é a mensagem que explica o motivo da imagem ser inválida.

Além disso, retornamos um enumerador *image_status* para que seja maepado o motivo da imagem ser inválida. Abaixo temos a listagem dos possíveis *image_status*:

image_status |  descrição
:----: | :---------:
no_faces | Nenhum rosto identificado.
multiple_faces | Mais de um rosto identificado.
close_face | Rosto muito próximo à câmera.
distant_face | Rosto muito distante à câmera.
not_centered | Rosto não está centralizado o suficiente.
inclined_face | Rosto está inclinado.
wearing_acessories | Pessoa está utilizando acessórios que cobrem parte do rosto.
facial_expression | A pessoa está com a boca aberta, sorrindo ou com os olhos fechados.
brightness_problem | A imagem não está com a iluminação adequada.
sharpness_problem | A imagem não está nítida o suficiente.

**Atenção -** Existem outros motivos pelos quais retornaremos 400 (Todos relacionados a dados inválidos). Somente os retornos com title "image_quality" são resultantes da validação de qualidade da imagem e portanto devem ser repassados ao usuário.

## Recuperação dos arquivos
> Recuperação de imagem

```shell
    curl "https://api.caas.qitech.app/face_recognition/image/f4b5337a-7b50-406e-8c8e-7d0e77b5aa02/file" \
         -H "Authorization: EXAMPLE_API_KEY"
```

Em qualquer momento é possível recuperar as imagens enviadas. Para isso, basta enviar  uma requisição **GET** adequadamente autenticada no endpoint:

`https://api.caas.qitech.app/face_recognition/image/{image_key}/file`

Onde image_key é o valor retornado durante o envio da imagem.

## Recuperação de arquivo processado
> Recuperação de imagem processada

```shell
    curl "https://api.caas.qitech.app/face_recognition/image/f4b5337a-7b50-406e-8c8e-7d0e77b5aa02/cropped_file" \
         -H "Authorization: EXAMPLE_API_KEY"
```
Após a associação de uma imagem a um cadastro ou uma validação, essa imagem será processada e uma nova imagem contendo apenas o rosto utilizado nas rotinas de reconhecimento facial será gerada.

Esta imagem está disponível para ser recuperada através de uma requisição **GET**, adequadamente autenticada, no endpoint:

`https://api.caas.qitech.app/face_recognition/image/{image_key}/cropped_file`

Onde image_key é o valor retornado durante o envio da imagem base.

## Recuperação dos meta-dados do arquivo
> Recuperação de meta dados

```shell
    curl "https://api.caas.qitech.app/face_recognition/image/f4b5337a-7b50-406e-8c8e-7d0e77b5aa02" \
         -H "Authorization: EXAMPLE_API_KEY"
```

Após o envio de uma imagem para a API, é possível recuperar os meta-dados da imagem utilizando o endpoint:

`https://api.caas.qitech.app/face_recognition/image/{image_key}`

Onde image_key é o valor retornado durante o envio da imagem.

---

# Introdução

URL: /documentation/caas/face_recognition/api/introduction

Bem vindo à API de Reconhecimento Facial da QI Tech! Você pode usar a nossa API para acessar os endpoints, cadastrar fotos de clientes e realizar o reconhecimento facial destes antes da execução de transações.

## Problemas?

Nós não somos uma companhia que se esconde atrás de uma API! Entre em contato com o nosso suporte e nós responderemos o mais rápido possível. Fique à vontade para nos ligar caso deseje uma resposta rápida!

### Adoramos Feedback

Mesmo que você já tenha resolvido o seu problema ou que ele seja muito simples (Até mesmo um typo ou uma organização inadequada que você já entendeu), envie-nos um e-mail, assim nós tornamos a documentação cada vez mais prática e a próxima pessoa não vai precisar sofrer as dores que você sofreu!

## Ambientes

Possuímos dois ambientes para os nossos clientes. As URLs base das APIs são:

* Produção - `https://api.caas.qitech.app/face_recognition/`
* Sandbox - `https://api.sandbox.caas.qitech.app/face_recognition/`

:::danger Aviso Importante!
Não devem ser usados dados reais de pessoas físicas e/ou jurídicas nos ambientes de Sandbox da QI Tech.  
:::

## Somente HTTPS

Por questão de segurança, toda a comunicação com as APIs da QI Tech deve ser realizada utilizando a comunicação HTTPS. Para evitar que, por desatenção ou outro motivo, sejam feitas chamadas HTTP, este servidor somente disponibiliza a porta 443 com comunicação TLS 1.2. Chamadas realizadas utilizando outros protocolos serão automaticamente negadas.

---

# Padrões

URL: /documentation/caas/face_recognition/api/standards

Para facilitar a integração e garantir a integridade da informação, foram definidos alguns padrões que são seguidos em toda a API.

## Data e Hora com Fuso Horário
> Alguns exemplos:

```
2019-10-15T22:35:12-03:00
2018-05-01T13:32:11+00:00
2019-05-01T00:00:00+00:00
```

É representada conforme a ISO 8601. Neste caso, o fuso-horário é colocado logo após o horário e deve representar o fuso do local onde aquele dado será valido. Por exemplo, se um aluguel estiver marcado para começar às 09:30 no aeroporto de Brasília, o horário enviado deverá ser representado por 09:30-03:00, se o aluguel estiver marcado para começar às 09:30 em Manaus, deverá ser representado por 09:30-04:00.

A máscara utilizada para validação é a seguinte:

`YYYY-MM-ddThh:mm:ss±hh:mm`

## Data e Hora sem Fuso Horario
> Alguns exemplos:

```
2019-10-15T22:35:12Z
2018-05-01T13:32:11Z
2019-05-01T00:00:00Z
```

É representada conforme a ISO 8601. Dados que independem de fuso-horário deverão ser enviados sem ele, sempre em UTC, com a letra Z indicando que este dado está em UTC. O seguinte formato, portanto, será validado:

`YYYY-MM-ddThh:mm:ssZ`

## Data
> Alguns exemplos

``` 
2019-10-15
2019-01-01
2017-03-20
```

No caso de campos que recebem somente data, uma data de nascimento, por exemplo, somente a data, sem nenhum horário deve ser enviada com o seguinte formato:

`YYYY-MM-dd`
 

## Documentos
Uma vez que os números de documento são bastante variados e muitos deles possuem caracteres que não se enquadram como numéricos, definem-se todos os números de documento como string. Outro bom motivo para definí-los como string é evitar que os zeros à esquerda desapareçam. Documentos previstos nesta página possuem uma máscara bem definida e estarão sujeitos a validação. O restante dos documentos, como RG, dada sua falta de padronização, não serão validados.

## CPF

> Exemplos de CPFs válidos contra a máscara definida:

```
123.456.789-12
321.987.543-23
111.283.333-00
```

> Exemplos de CPFs inválidos contra a máscara definida:

```
8.577.477-8
08.104.627/0001-23
123.456.789-1
23.456.789-01
```

O CPF é sempre definido como uma string e será validado contra a máscara:

`###.###.###-##`

---

# Coletando os Retornos

URL: /documentation/caas/face_recognition/flutter/collecting_response

O método `startFaceRecon` retorna um `Future `. Não é necessário realizar nenhuma decodificação manual de JSON — o plugin já entrega objetos Dart tipados.

## FaceReconReturnValues

```dart
class FaceReconReturnValues {
  final String imageKey;
  final String deviceScanSessionId;
}
```

| Atributo | Tipo | Descrição |
|----------|------|-----------|
|imageKey|String|Chave de identificação da imagem fornecida, que pode ser utilizada em qualquer outro serviço do sistema QI Tech. **Importante:** armazene este valor para enviar nas APIs de validação (ex.: API de Onboarding).|
|deviceScanSessionId|String|Chave de identificação da sessão de scan de dispositivo realizada internamente pelo SDK de Reconhecimento facial, que pode ser utilizada em qualquer outro serviço do sistema QI Tech.|

## FaceReconException

Em caso de falha, o método lança uma `FaceReconException` tipada:

```dart
class FaceReconException implements Exception {
  final int? statusCode;
  final String reason;
  final String description;
}
```

| Atributo | Tipo | Descrição |
|----------|------|-----------|
|statusCode|int?|Código HTTP do erro.|
|reason|String|Identificador do motivo do erro.|
|description|String|Descrição detalhada do erro.|

### Erros mais comuns

| reason | statusCode | description |
|--------|-----------|-------------|
|`INVALID_TOKEN`|401|`Authentication token expired or invalid` — o `clientSessionKey` é inválido ou expirou.|
|`USER_CANCELED`|0|`User canceled FaceRecon.` — o usuário interrompeu o fluxo antes de concluí-lo.|

## Exemplo de tratamento

```dart
try {
  final result = await plugin.startFaceRecon(
    CaaSEnvironment.sandbox,
    clientSessionKey,
  );

  print('Image key: ${result.imageKey}');
  print('Device Scan Session Id: ${result.deviceScanSessionId}');
} on FaceReconException catch (e) {
  print('Error executing FaceRecon:');
  print('Status: ${e.statusCode}');
  print('Reason: ${e.reason}');
  print('Description: ${e.description}');
} catch (e) {
  print('An unknown error occurred: $e');
}
```

---

# Compatibilidade

URL: /documentation/caas/face_recognition/flutter/compatibility

O plugin `flutter_kyc_qitech` exige as seguintes versões mínimas:

| Configuração | Versão mínima |
|------------|--------------|
|Flutter|3.3.0|
|Dart SDK|3.2.3|
|iOS|15.5|
|Android API Level|35 (Android 15 Vanilla Ice Cream)|
|Gradle|8.6.0|
|Android Gradle Plugin (AGP)|8.7|
|Kotlin|2.0.21 (recomendado)|
|Datadog SDK nativo (iOS, trazido pelo plugin)|3.x|
|MLKit FaceDetection (iOS, caso já utilizado no seu app)|8.x|

## Versão atual do plugin

| Plugin | Versão |
|--------|--------|
|`flutter_kyc_qitech`|`^5.3.0`|

:::warning Atenção
Nossos SDKs de iOS não suportam ser compilados para simuladores em máquinas com arquitetura **arm64** (MacBooks M1/M2/M3/M4), a menos que o **Rosetta** esteja ativo, traduzindo a arquitetura x86_64 para arm64. Recomendamos o uso de dispositivos físicos para testes.
:::

---

# Implementação

URL: /documentation/caas/face_recognition/flutter/example

O método `startFaceRecon` abre o fluxo nativo de prova de vida, envia a imagem capturada para a API de Reconhecimento facial da QI Tech e devolve a chave da imagem processada.

## Pré-requisito: obtendo o Client Session Key

O método `startFaceRecon` exige um `clientSessionKey`. Essa chave é temporária e deve ser gerada no seu backend por meio de uma requisição server-to-server para a nossa API, antes de chamar o método do SDK.

### Endpoint

| Ambiente | URL |
|----------|-----|
| **Sandbox** | `https://api.sandbox.zaig.com.br/face_recognition/client_session` |
| **Produção** | `https://api.zaig.com.br/face_recognition/client_session` |

### Requisição

**Method:** `POST`

**Headers:**

```json
{
  "Authorization": "YOUR_FACE_RECON_API_KEY"
}
```

**Body (Opcional, mas recomendado):**

```json
{
  "user_id": "unique_user_identifier"
}
```

> **Importante:** O campo `user_id` é **altamente recomendado** para medidas de segurança e antifraude. Use o CPF do cliente caso tenha acesso a essa informação.

### Resposta

A resposta bem-sucedida conterá o `client_session_key` que deve ser passado para o método `startFaceRecon`.

```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

:::danger Aviso Importante!
A API Key de Reconhecimento facial nunca deve ser embarcada no aplicativo. A requisição acima deve partir exclusivamente do seu backend.
:::

## Assinatura do método

```dart
Future<FaceReconReturnValues> startFaceRecon(
  CaaSEnvironment environment,
  String clientSessionKey, {
  FaceReconOptions? options,
})
```

Os dois primeiros parâmetros são posicionais e obrigatórios. As customizações são opcionais e passadas pelo parâmetro nomeado `options`, descrito em [O objeto FaceReconOptions](/documentation/caas/face_recognition/flutter/face_recon_options).

## Exemplo completo

```dart
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:flutter_kyc_qitech/flutter_kyc_qitech.dart';

final _qitechFlutterKycPlugin = FlutterKycQitech();

// Etapa 1: obter o clientSessionKey por meio do seu backend
Future<String?> fetchClientSessionKey() async {
  final response = await http.post(
    Uri.parse('<FACE_RECON_API_URL>'),
    headers: {
      HttpHeaders.authorizationHeader: '<API_KEY>',
      HttpHeaders.contentTypeHeader: 'application/json',
    },
    body: jsonEncode({'user_id': '<USER_IDENTIFICATION>'}),
  );

  if (response.statusCode == 200) {
    final data = jsonDecode(response.body);
    return data['client_session_key'] as String?;
  }
  return null;
}

// Etapa 2: iniciar o SDK com a chave obtida
Future<void> startFaceRecon() async {
  final clientSessionKey = await fetchClientSessionKey();

  if (clientSessionKey == null) {
    print('Failed to fetch clientSessionKey');
    return;
  }

  try {
    final result = await _qitechFlutterKycPlugin.startFaceRecon(
      CaaSEnvironment.sandbox,
      clientSessionKey,
      options: FaceReconOptions(
        sessionId: '<SESSION_ID>',
        documentNumber: '111.111.111-11',
        fontColor: '#FFFFFF',
        backgroundColor: '#000000',
        fontFamily: CaaSFontFamily.futura,
        showIntroductionScreens: true,
        showSuccessScreen: true,
        showInvalidTokenScreen: true,
        audioConfiguration: FaceReconAudioConfiguration.enable,
        onboardingTextConfiguration: OnboardingTextConfiguration(
          onboardingTitle: 'Conselhos relevantes',
          onboardingFirstLabel: 'Esteja com o rosto visível',
          onboardingSecondLabel: 'Encaixe seu rosto no oval',
          onboardingThirdLabel: 'Retire acessórios que cubram o rosto',
        ),
        logLevel: CaaSLogLevel.debug,
      ),
    );

    print('Image key: ${result.imageKey}');
    print('Device Scan Session Id: ${result.deviceScanSessionId}');
  } on FaceReconException catch (e) {
    print('Error executing FaceRecon:');
    print('Status: ${e.statusCode}');
    print('Reason: ${e.reason}');
    print('Description: ${e.description}');
  }
}
```

:::info **Atenção**
Habilite o suporte às orientações _Portrait_ e _Landscape Right_ em sua aplicação para o funcionamento correto do SDK nativo de iOS.
:::

## Aplicativo de exemplo

O repositório do plugin contém um aplicativo de exemplo pronto para execução, em `flutter_kyc_qitech/example`, que demonstra o uso dos três SDKs. Para executá-lo, crie um arquivo `.env` na pasta `example` com as credenciais abaixo e rode `flutter pub get` seguido de `flutter run` com um dispositivo físico conectado:

```
FACERECON_API_URL_SANDBOX=''
FACERECON_API_KEY_SANDBOX=''
OCR_MOBILE_TOKEN_SANDBOX=''
DEVICE_SCAN_API_URL_SANDBOX=''
DEVICE_SCAN_API_KEY_SANDBOX=''
```

Caso ainda não tenha recebido as suas credenciais, entre em contato com o suporte.caas@qitech.com.br .

---

# O objeto FaceReconOptions

URL: /documentation/caas/face_recognition/flutter/face_recon_options

## Parâmetros de startFaceRecon

| Parâmetro | Tipo | Função | Obrigatório |
|------------|--------------|--------------|--------------|
|environment|CaaSEnvironment|Enumerador utilizado para configurar o ambiente de execução para `sandbox` ou `production`.|Sim.|
|clientSessionKey|String|Chave temporária de autenticação obtida por meio de requisição server-to-server à API de Reconhecimento facial. Veja [Implementação](/documentation/caas/face_recognition/flutter/example).|Sim.|
|options|FaceReconOptions?|Objeto opcional com as customizações visuais, textuais e de comportamento do SDK.|Não.|

## FaceReconOptions

Todos os campos são opcionais. Quando um campo não é informado, o SDK nativo aplica o seu valor padrão.

| Parâmetro | Tipo | Função | Padrão |
|------------|--------------|--------------|--------------|
|sessionId|String?|Chave que identifica a sessão iniciada no SDK. É utilizada para rastrear todo o fluxo percorrido pelo usuário através de logs. Aceita até 255 caracteres.|Gerado internamente.|
|documentNumber|String?|Número do documento do usuário (CPF), utilizado exclusivamente para identificação antifraude.|Não enviado.|
|fontColor|String?|Cor da fonte e dos ícones das telas do SDK, em formato hexadecimal (ex.: `"#FFFFFF"`).|`"#000000"`|
|backgroundColor|String?|Cor de fundo das telas do SDK, em formato hexadecimal (ex.: `"#000000"`).|`"#FFFFFF"`|
|fontFamily|CaaSFontFamily?|Fonte utilizada nas telas do SDK.|`CaaSFontFamily.openSans`|
|showIntroductionScreens|bool?|Quando `false`, desativa as telas de introdução à prova de vida.|`true`|
|showSuccessScreen|bool?|Quando `false`, desativa a tela de sucesso exibida após a captura.|`true`|
|showInvalidTokenScreen|bool?|Quando `false`, desativa a tela exibida quando o `clientSessionKey` é inválido ou expirou.|`true`|
|audioConfiguration|FaceReconAudioConfiguration?|Configura o guiamento por voz, que narra as instruções de captura em tempo real.|`FaceReconAudioConfiguration.disable`|
|onboardingTextConfiguration|OnboardingTextConfiguration?|Customiza os textos da tela de onboarding.|Textos padrão do SDK.|
|logLevel|CaaSLogLevel?|Nível de verbosidade dos logs do SDK.|`CaaSLogLevel.debug`|

:::info **Atenção**
A partir da versão **5.0.0** do plugin, o campo `documentNumber` não dispara mais o registro de face — ele é utilizado somente para identificação antifraude.
:::

## OnboardingTextConfiguration

| Parâmetro | Tipo | Função |
|------------|--------------|--------------|
|onboardingTitle|String?|Título da tela de onboarding.|
|onboardingFirstLabel|String?|Primeira instrução exibida ao usuário.|
|onboardingSecondLabel|String?|Segunda instrução exibida ao usuário.|
|onboardingThirdLabel|String?|Terceira instrução exibida ao usuário.|

```dart
OnboardingTextConfiguration(
  onboardingTitle: 'Conselhos relevantes',
  onboardingFirstLabel: 'Esteja com o rosto visível',
  onboardingSecondLabel: 'Encaixe seu rosto no oval',
  onboardingThirdLabel: 'Retire acessórios que cubram o rosto',
)
```

## Enumeradores

### CaaSEnvironment

```dart
enum CaaSEnvironment {
  production,
  sandbox,
}
```

### CaaSFontFamily

```dart
enum CaaSFontFamily {
  jakarta,       // apenas iOS
  futura,        // iOS e Android
  verdana,       // iOS e Android
  trebuchetMs,   // apenas iOS
  tamilsangamMn, // apenas iOS
  openSans,      // iOS e Android
  helvetica,     // apenas Android
  poppins,       // apenas Android
  roboto,        // apenas Android
  systemFont,    // apenas iOS
}
```

:::info **Atenção**
A disponibilidade das fontes varia por plataforma. Caso uma fonte não suportada seja informada, a plataforma utiliza a sua fonte padrão. Para consistência entre iOS e Android, utilize `futura`, `verdana` ou `openSans`.
:::

### FaceReconAudioConfiguration

```dart
enum FaceReconAudioConfiguration {
  enable,        // exibe o botão de áudio, com a narração iniciando desligada
  disable,       // desativa a narração e oculta o botão
  accessibility, // exibe o botão com a narração iniciando ligada quando há recursos de acessibilidade ativos
}
```

### CaaSLogLevel

```dart
enum CaaSLogLevel {
  trace,
  debug,
  log,
  info,
  warn,
  error,
}
```

---

# Instalação

URL: /documentation/caas/face_recognition/flutter/installation

## Instalando o plugin

Execute o comando abaixo na raiz do seu projeto Flutter:

```bash
flutter pub add flutter_kyc_qitech
```

O comando instala a versão mais recente e adiciona a dependência ao seu `pubspec.yaml`:

```yaml
dependencies:
  flutter_kyc_qitech: ^5.3.0
```

Em seguida, baixe as dependências:

```bash
flutter pub get
```

## Importação

```dart
import 'package:flutter_kyc_qitech/flutter_kyc_qitech.dart';
```

E instancie o plugin:

```dart
final _qitechFlutterKycPlugin = FlutterKycQitech();
```

## Configuração do Android

### 1. Repositório Maven da QI Tech

Adicione a referência do repositório Android da QI Tech no `build.gradle` do projeto:

```gradle
allprojects {
    repositories {
        maven { url 'https://sdks.qitech.com.br/' }
        ...
    }
}
```

### 2. AdMob

Inicialize o serviço de AdMob adicionando o seguinte código no `AndroidManifest.xml`:

```xml
<meta-data
    android:name="com.google.android.gms.ads.APPLICATION_ID"
    android:value="<ADMOB_APP_ID>"/>
```

Caso não possua um `ADMOB_APP_ID`, entre em contato com o suporte.caas@qitech.com.br .

## Configuração do iOS

### 1. Permissão de câmera

Adicione a entrada `NSCameraUsageDescription` ao `Info.plist` do seu aplicativo, com o motivo pelo qual o app precisa de acesso à câmera:

```xml
<key>NSCameraUsageDescription</key>
<string>Precisamos da câmera para capturar a sua selfie</string>
```

### 2. Source do repositório iOS da QI Tech

Adicione as seguintes sources no topo do seu `Podfile`:

```ruby
source 'https://cdn.cocoapods.org/'
source 'https://github.com/QITechSDKs/iOS.git'
```

### 3. Frameworks estáticos

Por padrão, o CocoaPods constrói bibliotecas estáticas em vez de frameworks. Adicione ao seu `Podfile`:

```ruby
use_frameworks! :linkage => :static
```

### 4. Estabilidade de módulo

As dependências nativas da QI Tech exigem que o `BUILD_LIBRARY_FOR_DISTRIBUTION` esteja habilitado para os alvos do Datadog. Adicione o `post_install` abaixo (ou incorpore ao seu `post_install` existente):

```ruby
post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    target.build_configurations.each do |config|
      config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'NO'
      # A linha abaixo só é necessária para compilar em simuladores (com Rosetta ativo)
      config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
    end
    if ['DatadogCore', 'DatadogInternal', 'DatadogCrashReporting', 'DatadogLogs'].include?(target.name)
      target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
        config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
      end
    end
  end
end
```

### 5. Instalação dos pods

Na pasta `ios` do seu aplicativo Flutter, execute:

```bash
cd ios
pod install
```

ou, alternativamente, através do Flutter:

```bash
flutter build ios
```

:::warning Atenção
Se o seu aplicativo já utiliza **Datadog**, use a versão mais recente dentro do major `3.x` (`datadog_flutter_plugin` 3.x). Se utiliza o **FaceDetection do MLKit**, use a versão mais recente dentro do major `8.x`.
:::

---

# Introdução

URL: /documentation/caas/face_recognition/flutter/introduction

Bem vindo ao manual de integração do SDK de Reconhecimento facial da QI Tech em Flutter! O plugin `flutter_kyc_qitech` expõe, por meio de uma interface Dart, os SDKs nativos de Android (Kotlin) e iOS (Swift) da QI Tech. Você deve utilizá-lo para realizar a prova de vida (liveness) do seu cliente diretamente do seu aplicativo Flutter e referenciar a imagem capturada, através de uma chave, nos demais produtos do sistema QI Tech.

:::info **Plugin único para os três SDKs**

O `flutter_kyc_qitech` entrega os três SDKs de Risk Solutions no mesmo pacote: `startFaceRecon` (reconhecimento facial), `startOcr` (OCR) e `startDeviceScan` (scan de dispositivo). Ao instalá-lo, os três métodos ficam disponíveis — não é necessário instalar plugins adicionais.
:::

## Problemas?

Nós não somos uma companhia que se esconde atrás de uma API! Entre em contato com o nosso [suporte](mailto:suporte.caas@qitech.com.br) e nós responderemos o mais rápido possível. Fique à vontade para nos ligar caso deseje uma resposta rápida!

### Adoramos Feedback

Mesmo que você já tenha resolvido o seu problema ou que ele seja muito simples (Até mesmo um typo ou uma organização inadequada que você já entendeu), envie-nos um e-mail, assim nós tornamos a documentação cada vez mais prática e a próxima pessoa não vai precisar sofrer as dores que você sofreu!

## Ambientes

Possuímos dois ambientes para os nossos clientes. A seleção é realizada por meio do enumerador `CaaSEnvironment`, repassado como primeiro parâmetro do método `startFaceRecon`. No momento, os seguintes ambientes estão disponíveis:

* Produção - `CaaSEnvironment.production`
* Sandbox - `CaaSEnvironment.sandbox`

Cada ambiente exige uma API Key diferente para a geração do `clientSessionKey`.

:::danger Aviso Importante!
Não devem ser usados dados reais de pessoas físicas e/ou jurídicas nos ambientes de Sandbox da QI Tech.
:::

## Integração com Device Scan

O serviço de Reconhecimento facial realiza automaticamente uma chamada interna ao Device Scan. Por isso, o retorno de sucesso inclui o campo `deviceScanSessionId`, que identifica a sessão de scan de dispositivo realizada internamente e pode ser utilizada de forma integrada em outros serviços do ecossistema QI Tech.

## Próximos passos

1. [Compatibilidade](/documentation/caas/face_recognition/flutter/compatibility) — versões mínimas de Flutter, Dart, iOS e Android.
2. [Instalação](/documentation/caas/face_recognition/flutter/installation) — instalação do plugin e configuração nativa de Android e iOS.
3. [Implementação](/documentation/caas/face_recognition/flutter/example) — obtenção do `clientSessionKey` e exemplo completo da chamada `startFaceRecon`.
4. [O objeto FaceReconOptions](/documentation/caas/face_recognition/flutter/face_recon_options) — todos os parâmetros de customização.
5. [Coletando os Retornos](/documentation/caas/face_recognition/flutter/collecting_response) — estrutura de resposta e tratamento de erros.

---

# Coletando os Retornos do SDK

URL: /documentation/caas/face_recognition/ios/collecting_response

Para obter as respostas do SDK , você deve implementar o delegate **QITechIosFaceRecognitionControllerDelegate** em seu controller, conforme exemplo ao lado.

```swift
class ViewController: UIViewController, QITechIosFaceRecognitionControllerDelegate {
    
    // Do something if QI Tech FaceRecognition's SDK succesfully collected document picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFinishWithResults response: QITechIosFaceRecognitionControllerResponse) {
    
    }
    
    // Do something if QI Tech FaceRecognition's SDK found any error when collecting document picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFailWithError error: QITechIosFaceRecognitionControllerError) {
        
    }
    
    // Do something if the user canceled the picture collection on any steps
    func qitechIosFaceRecognitionControllerDidCancel(_ faceRecognitionViewController: QITechIosFaceRecognitionController) {

    }
}
```

## QITechIosFaceRecognitionControllerResponse

A classe **QITechIosFaceRecognitionControllerResponse** é utilizada para que você possa receber a resposta do SDK da QI Tech.

Na tabela abaixo você encontra o detalhe de todas as propriedades desta classe:

### Propriedades

:::info Aviso: 
Integração com Device Scan A partir da versão 6.1.0, o serviço de Face Recognition passa a realizar automaticamente uma chamada interna ao Device Scan. Com isso, o retorno de sucesso incluirá o campo `DeviceScanSessionId`. Esta chave identifica a sessão de scan de dispositivo realizada internamente e pode ser utilizada de forma integrada em outros serviços do ecossistema QI Tech. 
:::

| Nome | Tipo | Descrição |
|------|------|-----------|
| `FaceRecognitionKey` | `String` | Identificador único da foto do rosto armazenado na QI Tech. **Importante:** Armazene este valor para enviar nas APIs de validação (ex.: API de Onboarding). |
`DeviceScanSessionId` | `String` | Identificador único da sessão de scan de dispositivo realizada internamente. |

## QITechIosFaceRecognitionControllerError

A classe **QITechIosFaceRecognitionControllerError** é acionada quando ocorre um erro que leva ao encerramento do SDK.

:::danger Aviso Importante! 
A partir da versão **5.0.0**, a estrutura de erros foi reformulada para fornecer informações mais detalhadas e diagnósticas.
:::
#### Principais mudanças:

1. **Novos tipos de erro**: `InvalidToken` (substitui `InvalidMobileToken`)
2. **Novas propriedades disponíveis**:
   - `status_code`: Código HTTP do erro
   - `reason`: Identificador do motivo do erro
   - `description`: Descrição detalhada do erro

### Estrutura de Erro (SDK 5.0.0+)

#### Exemplo: InvalidToken

```swift
{
    status_code: 401,
    reason: "INVALID_TOKEN",
    description: "Authentication token expired or invalid"
}
```

## Tipos de Erro

### SDK 5.0.0 e posteriores

| Erro | Status Code | Descrição |
|------|-------------|-----------|
| `InvalidToken` | 401 | Token de autenticação expirado ou inválido (substitui `InvalidMobileToken`) |

### Versões anteriores à 5.0.0

| Classe de Erro | Descrição |
|----------------|-----------|
| `InvalidMobileToken` | MobileToken enviado nas configurações é inválido *(substituído por `InvalidToken` na v5.0.0+)* |
| `MissingPermission` | Alguma das permissões necessárias não foi concedida |
| `NetworkFailure` | Perda de conexão com a internet durante a validação |
| `ServerFailure` | Resposta de erro do servidor da QI Tech |
| `MissingStorage` | Espaço de armazenamento insuficiente |
| `LowImageQuality` | Qualidade da imagem insuficiente para validação |

---

# QITechIosFaceRecognitionConfiguration

URL: /documentation/caas/face_recognition/ios/configuration

## SDK 7.0.0 e posteriores
```swift
let onboardingTextConfiguration = OnboardingTextConfiguration(
        onboardingTitle: "Conselhos relevantes",
        onboardingFirstLabel: "Esteja com o rosto visível",
        onboardingSecondlabel: "Encaixe seu rosto no oval",
        onboardingThirdLabel: "Retire acessórios que cubram o rosto"
)

let faceRecognitionConfig = QITechIosFaceRecognitionConfiguration(
        environment: QITechIosFaceRecognitionEnvironment.sandbox,
        clientSessionKey: clientSessionKey,
        sessionId: "7d8c6f9a-f222-450d-9501-a07c68eb2388",
        documentNumber: "123.456.789-00",
        fontColor: "#337DFF",
        backgroundColor: "#C9CCD3",
        fontFamily: .open_sans,
        showIntroductionScreens: true,
        showSuccessScreen: true,
        showInvalidTokenScreen: false,
        audioConfiguration: AudioConfiguration.enable,
        onboardingTextConfiguration: onboardingTextConfiguration,
        logLevel: .debug
)
```

**Versões anteriores à v7.0.0**
```swift
let visualConfiguration = VisualConfiguration()
        visualConfiguration.setOnboarding(onboardingFilePath: Bundle.main.path(forResource: "onboarding", ofType: "png")!, onboardingWidth: 200)

let textConfiguration = TextConfiguration()
        textConfiguration.setCustomText(on: .onboardingTitle, text: "Para tirar uma boa foto:")
        textConfiguration.setCustomText(on: .onboardingFirstLabel, text: "- Vá para um local iluminado")
        textConfiguration.setCustomText(on: .onboardingSecondLabel, text: "- Retire adereços e mostre bem o rosto")
        textConfiguration.setCustomText(on: .onboardingThirdLabel, text: "- Insira seu rosto na moldura, aguardando que fique verde para realizar a captura")

let faceRecognitionConfig = QITechIosFaceRecognitionConfiguration(environment: QITechIosFaceRecognitionEnvironment.Sandbox,
                                            clientSessionKey: clientSessionKey,
                                            sessionId: "7d8c6f9a-f222-450d-9501-a07c68eb2388",
                                            backgroundColor: "#C9CCD3",
                                            fontColor: "#337DFF",
                                            fontFamily: .open_sans,
                                            showIntroductionScreens: true,
                                            showSuccessScreen: false,
                                            showInvalidTokenScreen: true,
                                            activeFaceLiveness: true,
                                            audioConfiguration: AudioConfiguration.Enable,
                                            logLevel: .debug
                                            )

faceRecognitionConfig.setVisualConfiguration(visualConfiguration: visualConfiguration)
faceRecognitionConfig.setTextConfiguration(textConfiguration: textConfiguration)
```

A classe **QITechIosFaceRecognitionConfiguration** é utilizada para que você possa configurar ambiente, credenciais, aspectos visuais e textuais ou seja, todas as configurações necessárias para personalização e funcionamento do SDK.

Na tabela abaixo você encontra o detalhe de todos os argumentos que devem ser utilizados na sua instanciação:

| nome                    |               tipo                | descrição                                                                                                                                                                                                                                                                                                                                   |
| ----------------------- | :-------------------------------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| environment             | QITechIosFaceRecognitionEnvironment | _(obrigatório)_ Enumerador que descreve o ambiente.                                                                                                                                                                                                                                                                                         |
| clientSessionKey        |              string               | _(obrigatório)_ Token enviado pela API face recognition para autenticação do SDK.                                                                                                                                                                                                                                                                        |
| sessionId               |              string               | _(opcional)_ ID único usado para rastrear todo fluxo percorrido pelo usuário na execução da FaceRecon através de logs. Este campo aceita até 255 caracteres.                                                                                                                                                                                |
| documentNumber          |              string               | _(opcional)_ Utilizado para identificação do usuário para anti-fraude e segurança interna |
| fontColor               |              string               | _(opcional)_ Hexadecimal da cor da fonte. Caso não seja informada o padrão é #1C49A5.                                                                                                                                                                                                                                                       |
| backgroundColor         |              string               | _(opcional)_ Hexadecimal da cor de fundo das telas. Caso não seja informada o padrão é #FCFCFC.                                                                                                                                                                                                                                             |
| fontFamily              |            FontFamily             | _(opcional)_ Familia da fonte. Caso não seja informada o padrão é .open_sans. Fontes disponíveis: .open_sans, .futura, .verdana, .trebuchetms, .tamilsangammn e .system_font.                                                                                                                                                               |
| showIntroductionScreens |             booleano              | _(opcional)_ Flag que indica se as telas de introdução, com instruções de como a foto deve ser capturada, devem ser mostradas. Caso não seja informada o padrão é _true_.                                                                                                                                                                   |
| showSuccessScreen       |             booleano              | _(opcional)_ Flag que indica se a tela de sucesso, com a mensagem de sucesso na captura, deve ser mostrada. Caso não seja informada o padrão é _true_.                                                                                                                                                                                      |
| showInvalidTokenScreen  |             booleano              | _(opcional)_ Flag que indica se a tela de falha de autenticação, com a mensagem de expiração de token, deve ser mostrada. Caso não seja informada o padrão é _true_. |
| audioConfiguration      |        AudioConfiguration         | _(opcional)_ Configura o guiamento por voz do SDK, que narra as instruções de captura em tempo real. As configurações aceitas são: _Enable_, que exibe o botão de ligar/desligar áudio com a narração iniciando desligada; _Disable_, que desativa a narração e oculta o botão; e _Accessibility_, que exibe o botão com a narração iniciando ligada quando o dispositivo possui recursos de acessibilidade ativos. Com o VoiceOver ativo, as instruções completas são entregues pelo próprio leitor de telas. |
| onboardingTextConfiguration | OnboardingTextConfiguration | _(opcional)_ Permite configurar os textos da tela de instruções |
| logLevel                |             LogLevel              | _(opcional)_ Utilizado para customizar o nível de verbosidade dos logs do SDK. Níveis disponíveis: LogLevel.debug, LogLevel.info, LogLevel.warn, LogLevel.error e LogLevel.trace. Caso não seja informada o padrão é LogLevel.debug. |

Na tabela abaixo você encontra todos os métodos aceitos pela instância para configuração:
:::warning
__DEPRECADO__ A PARTIR DA **v7.0.0**!
:::

| método                 |                                                                                                                     argumentos                                                                                                                     | descrição                                                                                     |
| ---------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | --------------------------------------------------------------------------------------------- |
| setVisualConfiguration |                                                                 visualConfiguration : VisualConfiguration                                                             | _(opcional)_ Classe que permite a modificação das imagens exibidas durante a execução do SDK; |
| setTextConfiguration   |                                                                                                       textConfiguration : TextConfiguration                                                                                                        | _(opcional)_ Classe que permite a modificação dos textos exibidos durante a execução do SDK;  |
| setDocumentNumber      |                                                    Utilizado para definir o número do documento do usuário. Este campo aceita 14 caracteres do CPF formatado da seguinte maneira 000.000.000-00                                                    | Sim em todas as chamadas caso use a validação 1:1 em algum momento.                                                                                         |
| setValidation          | Utilizado para definir se o SDK deve ou não realizar a validação 1:1 com a selfie do usuário. Na primeira sessão do usuário esta flag deve estar **obrigatoriamente false**. Esta função depende necessita do método setDocumentNumber preenchido. | Não. O padrão é _false_.                                                                      |

---

# Introdução

URL: /documentation/caas/face_recognition/ios/introduction

Bem vindo ao SDK iOS de Reconhecimento Facial da QI Tech. Este SDK realiza a captura de face e seu envio para a API de Face Recognition da QI Tech . Você pode utilizá-lo para capturar através do seu aplicativo uma imagem do rosto de um cliente e referenciá-lo através de uma chave nos demais produtos do sistema QI Tech.

## Problemas?

Nós não somos uma companhia que se esconde atrás de uma API! Entre em contato com o nosso [suporte](mailto:suporte.caas@qitech.com.br) e nós responderemos o mais rápido possível. Fique à vontade para nos ligar caso deseje uma resposta rápida!

### Adoramos Feedback

Mesmo que você já tenha resolvido o seu problema ou que ele seja muito simples (Até mesmo um typo ou uma organização inadequada que você já entendeu), envie-nos um e-mail, assim nós tornamos a documentação cada vez mais prática e a próxima pessoa não vai precisar sofrer as dores que você sofreu!

:::danger Aviso Importante!
Não devem ser usados dados reais de pessoas físicas e/ou jurídicas nos ambientes de Sandbox da QI Tech.  
:::

---

# Importando o SDK

URL: /documentation/caas/face_recognition/ios/native_swift

## Remotamente

> Iniciando a instalação

```shell
  pod init
```

Nosso SDK pode ser importado utilizando CocoaPods.

| SDK              | Versão atual                         |
| ---------------- | ------------------------------------ |
| QITechIosFaceRecon | `pod 'QITechIosFaceRecon', '~> 8.2.0'` |

:::info iOS Minimum Deployment Target
15.5
:::

:::danger Utilização de simuladores em MacBooks com chip arm64
Atualmente, nosso SDK de FaceRecon para iOS infelizmente não suporta ser compilada para simuladores que estejam rodando
em um MacBook com **chip de arquitetura arm64** (M1/M2/M3/M4), **a não ser que seja utilizado Rosetta**, que faz a tradução
da arquitetura x86_64 para arm64.
:::

Para iniciar a instalação, execute o comando ao lado na pasta raiz do seu projeto.

> Adicionando a source no podfile

```ruby
   source 'https://github.com/QITechSDKs/iOS.git'
   source 'https://cdn.cocoapods.org/'
```

O próximo passo é adicionar no arquivo `podfile` o source da QI Tech.

> Adicionando o pod no podfile

```ruby
  pod 'QITechIosFaceRecon', '~> <version>'
```

Por fim, basta adicionar o nome do `pod` de acordo com o formato ao lado.

:::danger Atenção: 
Mudança de Arquitetura (v6.0.0+) A partir da versão 6.0.0, o SDK passou a ser distribuída exclusivamente de forma estática. No seu Podfile, você deve utilizar a configuração :linkage => :static. 
:::

> Exemplo de podfile (Versão 6.0.0 ou superior)

```ruby
  source 'https://github.com/QITechSDKs/iOS.git'
  source 'https://cdn.cocoapods.org/'
  target 'ExampleApp' do
    use_frameworks! :linkage => :static
    pod 'QITechIosFaceRecon', '~> 8.2.0'
  end

  post_install do |installer|
    installer.pods_project.targets.each do |target|
      if ['DatadogCore', 'DatadogInternal', 'DatadogCrashReporting', 'DatadogLogs'].include?(target.name)
        target.build_configurations.each do |config|
          config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
          config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
        end
      end
    end
  end
```

> Exemplo de podfile (Versão Anteriores) 

```ruby
  source 'https://github.com/QITechSDKs/iOS.git'
  source 'https://cdn.cocoapods.org/'
  target 'ExampleApp' do
    use_frameworks!
    pod 'QITechIosFaceRecon', '~> 5.0.0'
  end

  post_install do |installer|
    installer.pods_project.targets.each do |target|
      if ['DatadogCore', 'DatadogInternal', 'DatadogCrashReporting', 'DatadogLogs'].include?(target.name)
        target.build_configurations.each do |config|
          config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
          config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
        end
      end
    end
  end
```

:::warning Atenção
Ao integrar dependências no iOS, pode surgir a necessidade de usar linkagem estática para algumas bibliotecas e dinâmica para outras. Essa configuração é relevante para garantir compatibilidade, evitar erros de build e otimizar o desempenho do projeto. 
:::

### Linkagem Híbrida de Dependências (caso necessário)
A necessidade de linkagem híbrida surge porque algumas bibliotecas têm requisitos específicos, sendo que algumas precisam de linkagem estática para evitar conflitos internos e duplicação de símbolos e outras dependências podem precisar linkagem dinâmica, pois são projetadas para modularidade e compartilhamento entre projetos.

Diferenças Entre Linkagem Estática e Dinâmica
* Estática (static_framework): O código da biblioteca é incorporado diretamente no binário final, reduzindo o tempo de carregamento em runtime e eliminando dependências externas durante a execução.
* Dinâmica (dynamic_framework): A biblioteca é carregada em tempo de execução como um arquivo separado. Isso reduz o tamanho do binário final e facilita atualizações/modificações independentes.

> Configurando linkagem híbrida no Podfile

```ruby
...

use_frameworks! :linkage => :dynamic # CONFIGURANDO O MODO PADRÃO DE LINKAGEM PARA DINÂMICO

...

static_frameworks = ['framework_1', 'framework_2', ...] # INCLUIR TODAS AS DEPENDÊNCIAS QUE PRECISAM SER LINKADAS DE MODO ESTÁTICO
pre_install do |installer|
  installer.pod_targets.each do |pod|
    if static_frameworks.include?(pod.name)
      def pod.static_framework?;
        true
      end
      def pod.build_type;
        Pod::BuildType.static_framework
      end
    end
  end
end
```

> Instalando as dependências

```shell
  pod install
```

Por fim, execute o comando `pod install` para baixar e instalar as dependências.

## Permissões Necessárias

Para que o SDK possa acessar os recursos do dispositivo para coletar a selfie do usuário, é necessário que sejam solicitadas permissões ao usuário.

No arquivo **info.plist**, adicione as permissões abaixo:

| Permissão                          | Motivo                                             |
| ---------------------------------- | -------------------------------------------------- |
| Privacy - Camera Usage Description | Acesso à câmera para capturar a selfie do usuário. |

## Iniciando o SDK

:::danger Aviso Importante!
A partir da versão 5.0.0, o sistema de autenticação foi atualizado para usar **clientSessionKey** em vez de **mobileToken**. Além disso, foram adicionadas novas opções de configuração para telas de feedback.
:::

### Obtendo o Client Session Key

Antes de configurar o SDK, você deve gerar um **clientSessionKey** temporário através de uma requisição server-to-server para a nossa API de face recognition.

### Endpoint

| Ambiente | URL |
|----------|-----|
| **Sandbox** | `https://api.sandbox.zaig.com.br/face_recognition/client_session` |
| **Produção** | `https://api.zaig.com.br/face_recognition/client_session` |

### Requisição

**Method:** `POST`

**Headers:**
```json
{
  "Authorization": "YOUR_FACE_RECON_API_KEY"
}
```

**Body (Opcional, mas recomendado):**
```json
{
  "user_id": "unique_user_identifier"
}
```

> **Importante:** O campo `user_id` é **altamente recomendado** para medidas de segurança e antifraude. Use um identificador único do usuário da sua aplicação.

### Resposta

A resposta bem-sucedida conterá o `client_session_key` que deve ser passado para a configuração do SDK.

```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

### Exemplo de inicialização do SDK

```swift

import QITechIosFaceRecognition

class ViewController: UIViewController, QITechIosFaceRecognitionControllerDelegate {

    var qitechFaceRecognitionConfiguration : QITechIosFaceRecognitionConfiguration?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setupFaceRecognition()
    }

    func setupFaceRecognition() -> Void {
      let clientSessionKey = try await fetchClientSessionKey()
                    
      let onboardingTextConfiguration = OnboardingTextConfiguration(
          onboardingTitle: "Conselhos relevantes",                     // Título
          onboardingFirstLabel: "Esteja com o rosto visível",          // Primeira Instrução
          onboardingSecondlabel: "Encaixe seu rosto no oval",          // Segunda Instrução
          onboardingThirdLabel: "Retire acessórios que cubram o rosto" // Terceira Instrução
      )

      self.faceRecognitionConfig = QITechIosFaceRecognitionConfiguration(
          environment: QITechIosFaceRecognitionEnvironment.sandbox,
          clientSessionKey: clientSessionKey,
          sessionId: "test_session_id",
          documentNumber: "123.456.789-00",
          fontColor: "#AB9FF2",
          backgroundColor: "#FFFDF8",
          fontFamily: .futura,
          showIntroductionScreens: true,
          showSuccessScreen: true,
          showInvalidTokenScreen: false,
          audioConfiguration: AudioConfiguration.enable,
          onboardingTextConfiguration: onboardingTextConfiguration,
          logLevel: .debug 
      )
    }

    // Event where you intend to call QI Tech FaceRecognition View Controller - on this example, when the user press 'next' button

    @IBAction func pressNext(_ sender: Any) {
        let qitechFaceRecognitionController = QITechIosFaceRecognitionController(faceRecognitionConfiguration: self.faceRecognitionConfig)
        qitechFaceRecognitionViewController.delegate = self
        let qitechFaceRecognitionViewController =  qitechFaceRecognitionController.getViewController()
        present(qitechFaceRecognitionViewController, animated: true, completion: nil)
    }

    // Do something if QI Tech FaceRecognition's SDK successfully collected picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFinishWithResults results: QITechIosFaceRecognitionControllerResponse) {

    }

    // Do something if QI Tech FaceRecognition's SDK found any error when collecting  picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFailWithError error: QITechIosFaceRecognitionControllerError) {

    }

    // Do something if the user canceled the picture collection on any steps
    func qitechIosFaceRecognitionControllerDidCancel(_ faceRecognitionViewController: QITechIosFaceRecognitionController) {

    }
}
```

**Versões anteriores à v7.0.0**
```swift

import QITechIosFaceRecognition

class ViewController: UIViewController, QITechIosFaceRecognitionControllerDelegate {

    var qitechFaceRecognitionConfiguration : QITechIosFaceRecognitionConfiguration?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setupFaceRecognition()
    }

    func setupFaceRecognition() -> Void {
        // The environment can be 'Sandbox' ou 'Production'
        let environment = QITechIosFaceRecognitionEnvironment.Sandbox

        // ClientSessionKey is the key you got via Face Recognition request. Each environment requires a different API_KEY.
        let clientSessionKey = fetchClientSessionKey()

        self.faceRecognitionConfig = QITechIosFaceRecognitionConfiguration(environment: environment,
                                            clientSessionKey: clientSessionKey,
                                            sessionId: "UNIQUE_SESSION_ID",
                                            backgroundColor: "#000000",
                                            fontColor: "#FFFFFF",
                                            fontFamily: .open_sans,
                                            showIntroductionScreens: true,
                                            showSuccessScreen: false,
                                            showInvalidTokenScreen: true,
                                            activeFaceLiveness: true,
                                            audioConfiguration: AudioConfiguration.Enable,
                                            logLevel: .debug
                                            )
    }

    // Event where you intend to call QI Tech FaceRecognition View Controller - on this example, when the user press 'next' button

    @IBAction func pressNext(_ sender: Any) {
        let qitechFaceRecognitionController = QITechIosFaceRecognitionController(faceRecognitionConfiguration: self.faceRecognitionConfig)
        qitechFaceRecognitionViewController.delegate = self
        let qitechFaceRecognitionViewController =  qitechFaceRecognitionController.getViewController()
        present(qitechFaceRecognitionViewController, animated: true, completion: nil)
    }

    // Do something if QI Tech FaceRecognition's SDK successfully collected picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFinishWithResults results: QITechIosFaceRecognitionControllerResponse) {

    }

    // Do something if QI Tech FaceRecognition's SDK found any error when collecting  picture
    func qitechIosFaceRecognitionController(_ faceRecognitionViewController: QITechIosFaceRecognitionController, didFailWithError error: QITechIosFaceRecognitionControllerError) {

    }

    // Do something if the user canceled the picture collection on any steps
    func qitechIosFaceRecognitionControllerDidCancel(_ faceRecognitionViewController: QITechIosFaceRecognitionController) {

    }
}
```

Para incorporar o SDK ao seu aplicativo você deve realizar a configuração do seu aplicativo de captura personalizado através da classe **QITechIosFaceRecognitionConfiguration** e depois instanciar o **ViewController QITechIosFaceRecognitionController** passando como argumento as configurações personalizadas.

Para iniciar o processo de análise de face, basta chamar a função _present_ para chamar o ViewController da QI Tech que realizará a coleta da selfie.

Importante implementar o _Delegate_ responsável por receber os retornos em caso de sucesso, erro ou no caso de o usuário interromper a jornada em qualquer etapa da validação.

Acima temos um exemplo completo da implementação.

---

# Coletando os Retornos

URL: /documentation/caas/face_recognition/react_native/collecting_response

A função `startFaceRecon` retorna uma _Promise_ que resolve com um objeto já tipado — diferentemente do `startOcr`, não é necessário chamar `JSON.parse()`.

## Resolução da Promise

```typescript
type FACE_RECON_RETURN_VALUES = {
  image_key: string;
  device_scan_session_id: string;
};
```

| Atributo | Tipo | Descrição |
|----------|------|-----------|
|image_key|string|Chave de identificação da imagem fornecida, que pode ser utilizada em qualquer outro serviço do sistema QI Tech. **Importante:** armazene este valor para enviar nas APIs de validação (ex.: API de Onboarding).|
|device_scan_session_id|string|Chave de identificação da sessão de scan de dispositivo realizada internamente pelo SDK de Reconhecimento facial, que pode ser utilizada em qualquer outro serviço do sistema QI Tech.|

```json
{
  "image_key": "5d0f0e1c-8f9e-4b6c-9c3d-2f8a1b4e7c10",
  "device_scan_session_id": "a1b2c3d4-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
}
```

## Rejeição da Promise

Em caso de falha, a _Promise_ é rejeitada com um objeto do tipo `FACE_RECON_ERROR`:

```typescript
type FACE_RECON_ERROR = {
  status_code: number;
  reason: string;
  description: string;
};
```

| Atributo | Tipo | Descrição |
|----------|------|-----------|
|status_code|number|Código HTTP do erro.|
|reason|string|Identificador do motivo do erro.|
|description|string|Descrição detalhada do erro.|

### Erros mais comuns

| reason | status_code | description |
|--------|-------------|-------------|
|`INVALID_TOKEN`|401|`Authentication token expired or invalid` — o `client_session_key` é inválido ou expirou.|
|`USER_CANCELED`|0|`User canceled FaceRecon.` — o usuário interrompeu o fluxo antes de concluí-lo.|

## Exemplo de tratamento

```tsx
startFaceRecon(CAAS_ENVIRONMENT.SANDBOX, clientSessionKey)
  .then((response) => {
    console.log('Image Key: ', response.image_key);
    console.log('Device Scan Session Id: ', response.device_scan_session_id);
  })
  .catch((error) => {
    // Opcional: type assertion (cast) para FACE_RECON_ERROR.
    // Recomendado para garantir type safety em TypeScript.
    const reconError = error as FACE_RECON_ERROR;

    console.error('Status:', reconError.status_code);
    console.error('Reason:', reconError.reason);
    console.error('Description:', reconError.description);
  });
```

---

# Compatibilidade

URL: /documentation/caas/face_recognition/react_native/compatibility

O módulo `@qitech/react-native-caas` exige as seguintes versões mínimas:

| Configuração | Versão mínima |
|------------|--------------|
|React Native|0.74|
|React|18.2.0|
|iOS|15.5|
|Android API Level|35 (Android 15)|
|Datadog SDK nativo (iOS, trazido pelo módulo)|3.x|
|MLKit FaceDetection (iOS, caso já utilizado no seu app)|8.x|

## Versão atual do pacote

| Pacote | Versão |
|--------|--------|
|`@qitech/react-native-caas`|`11.3.0`|
|`@qitech/react-native-device-scan`|`1.2.0`|

:::warning Atenção
Nossos SDKs de iOS só suportam simuladores em máquinas com arquitetura **arm64** (M1/M2/M3/M4) com o **Rosetta** ativo, traduzindo a arquitetura x86_64. Recomendamos o uso de dispositivos físicos para testes.
:::

## Expo

O pacote inclui um _config plugin_ do Expo que aplica automaticamente as configurações nativas de iOS e Android. Veja [Instalação](/documentation/caas/face_recognition/react_native/installation).

:::info **Atenção**
O módulo não funciona no _Expo managed workflow_ sem `prebuild` — é necessário gerar os projetos nativos com `npx expo prebuild`.
:::

---

# Implementação

URL: /documentation/caas/face_recognition/react_native/example

A função `startFaceRecon` abre o fluxo nativo de prova de vida, envia a imagem capturada para a API de Reconhecimento facial da QI Tech e devolve a chave da imagem processada.

## Pré-requisito: obtendo o Client Session Key

A função `startFaceRecon` exige um `client_session_key`. Essa chave é temporária e deve ser gerada no seu backend por meio de uma requisição server-to-server para a nossa API, antes de chamar a função do SDK.

### Endpoint

| Ambiente | URL |
|----------|-----|
| **Sandbox** | `https://api.sandbox.zaig.com.br/face_recognition/client_session` |
| **Produção** | `https://api.zaig.com.br/face_recognition/client_session` |

### Requisição

**Method:** `POST`

**Headers:**

```json
{
  "Authorization": "YOUR_FACE_RECON_API_KEY"
}
```

**Body (Opcional, mas recomendado):**

```json
{
  "user_id": "unique_user_identifier"
}
```

> **Importante:** O campo `user_id` é **altamente recomendado** para medidas de segurança e antifraude. Use o CPF do cliente caso tenha acesso a essa informação.

### Resposta

A resposta bem-sucedida conterá o `client_session_key` que deve ser passado para a função `startFaceRecon`.

```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

:::danger Aviso Importante!
A API Key de Reconhecimento facial nunca deve ser embarcada no aplicativo. A requisição acima deve partir exclusivamente do seu backend.
:::

## Assinatura da função

```javascript
const result = await startFaceRecon(
  environment,         // CAAS_ENVIRONMENT
  client_session_key,  // string
  options              // FaceReconOptions (opcional)
);
```

As customizações são opcionais e passadas pelo objeto `options`, descrito em [O objeto FaceReconOptions](/documentation/caas/face_recognition/react_native/face_recon_options).

## Exemplo completo

```tsx
import * as React from 'react';
import { useCallback } from 'react';
import { View, Button } from 'react-native';
import {
  CAAS_ENVIRONMENT,
  CAAS_FONT_FAMILY,
  CAAS_LOG_LEVEL,
  FACE_RECON_AUDIO_CONFIGURATION,
  FACE_RECON_ERROR,
  startFaceRecon,
} from '@qitech/react-native-caas';

const FACE_RECON_API_URL = 'https://api.sandbox.zaig.com.br/face_recognition/client_session';
const FACE_RECON_API_KEY = '<FACE_RECON_API_KEY>';

const config = {
  environment: CAAS_ENVIRONMENT.SANDBOX,
  sessionId: '<SESSION_ID>',
  documentNumber: '111.111.111-11',
  fontColor: '#5dcfe3',
  backgroundColor: '#f5f3f0',
  fontFamily: CAAS_FONT_FAMILY.VERDANA,
  showIntroductionScreens: true,
  showSuccessScreen: true,
  showInvalidTokenScreen: true,
  logLevel: CAAS_LOG_LEVEL.DEBUG,
};

export default function App() {
  // Etapa 1: obter o client_session_key por meio do seu backend
  const fetchClientSessionKey = useCallback(async () => {
    const response = await fetch(FACE_RECON_API_URL, {
      method: 'POST',
      headers: {
        'Authorization': FACE_RECON_API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ user_id: '<USER_IDENTIFICATION>' }),
    });

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`);
    }

    const data = await response.json();

    if (!data.client_session_key) {
      throw new Error("No 'client_session_key' found.");
    }

    return data.client_session_key;
  }, []);

  // Etapa 2: iniciar o SDK com a chave obtida
  const startFr = async () => {
    const clientSessionKey = await fetchClientSessionKey();

    startFaceRecon(config.environment, clientSessionKey, {
      session_id: config.sessionId,
      document_number: config.documentNumber,
      font_color: config.fontColor,
      background_color: config.backgroundColor,
      font_family: config.fontFamily,
      show_introduction_screens: config.showIntroductionScreens,
      show_success_screen: config.showSuccessScreen,
      show_invalid_token_screen: config.showInvalidTokenScreen,
      audio_configuration: FACE_RECON_AUDIO_CONFIGURATION.ENABLE,
      onboarding_text_configuration: {
        onboarding_title: 'Conselhos relevantes',
        onboarding_first_label: 'Esteja com o rosto visível',
        onboarding_second_label: 'Encaixe seu rosto no oval',
        onboarding_third_label: 'Retire acessórios que cubram o rosto',
      },
      log_level: config.logLevel,
    })
      .then((response) => {
        // image_key identifica a imagem na QI Tech — armazene e envie na API de Onboarding
        console.log('Face Recon successfully ended. Image Key: ', response.image_key);
        // device_scan_session_id identifica a chamada interna ao Device Scan
        console.log('Device Scan Session Id: ', response.device_scan_session_id);
      })
      .catch((error) => {
        const reconError = error as FACE_RECON_ERROR;

        console.error('Error executing FaceRecon:');
        console.error('Status:', reconError.status_code);
        console.error('Reason:', reconError.reason);
        console.error('Description:', reconError.description);
      });
  };

  return (
    <View>
      <Button title="Start FaceRecon" onPress={startFr} />
    </View>
  );
}
```

## Aplicativos de exemplo

O repositório do módulo contém dois aplicativos prontos para execução, na pasta `examples`:

* **QITechReactNativeExample** — React Native puro
* **QITechExpoExample** — Expo

Em ambos, o arquivo `App.tsx` demonstra o uso completo (Reconhecimento facial + OCR + Scan de dispositivo) com o `@qitech/react-native-caas`. Substitua os tokens e API Keys de exemplo pelas suas credenciais. Caso ainda não as tenha recebido, entre em contato com o suporte.caas@qitech.com.br .

---

# O objeto FaceReconOptions

URL: /documentation/caas/face_recognition/react_native/face_recon_options

## Parâmetros de startFaceRecon

| Parâmetro | Tipo | Função | Obrigatório |
|------------|--------------|--------------|--------------|
|environment|CAAS_ENVIRONMENT|Enumerador utilizado para configurar o ambiente de execução para `SANDBOX` ou `PRODUCTION`.|Sim.|
|client_session_key|string|Chave temporária de autenticação obtida por meio de requisição server-to-server à API de Reconhecimento facial. Veja [Implementação](/documentation/caas/face_recognition/react_native/example).|Sim.|
|options|FaceReconOptions|Objeto opcional com as customizações visuais, textuais e de comportamento do SDK.|Não.|

## FaceReconOptions

Todos os campos são opcionais. Quando um campo não é informado, o SDK nativo aplica o seu valor padrão.

```typescript
type FaceReconOptions = {
  session_id?: string;
  document_number?: string;
  font_color?: string;
  background_color?: string;
  font_family?: CAAS_FONT_FAMILY;
  show_introduction_screens?: boolean;
  show_success_screen?: boolean;
  show_invalid_token_screen?: boolean;
  audio_configuration?: FACE_RECON_AUDIO_CONFIGURATION;
  onboarding_text_configuration?: OnboardingTextConfiguration;
  log_level?: CAAS_LOG_LEVEL;
};
```

| Parâmetro | Tipo | Função | Padrão |
|------------|--------------|--------------|--------------|
|session_id|string|Chave que identifica a sessão iniciada no SDK. É utilizada para rastrear todo o fluxo percorrido pelo usuário através de logs. Aceita até 255 caracteres.|Gerado internamente.|
|document_number|string|Número do documento do usuário (CPF), utilizado exclusivamente para identificação antifraude.|Não enviado.|
|font_color|string|Cor da fonte e dos ícones das telas do SDK, em formato hexadecimal (ex.: `"#FFFFFF"`).|`"#000000"`|
|background_color|string|Cor de fundo das telas do SDK, em formato hexadecimal (ex.: `"#000000"`).|`"#FFFFFF"`|
|font_family|CAAS_FONT_FAMILY|Fonte utilizada nas telas do SDK.|`CAAS_FONT_FAMILY.OPEN_SANS`|
|show_introduction_screens|boolean|Quando `false`, desativa as telas de introdução à prova de vida.|`true`|
|show_success_screen|boolean|Quando `false`, desativa a tela de sucesso exibida após a captura.|`true`|
|show_invalid_token_screen|boolean|Quando `false`, desativa a tela exibida quando o `client_session_key` é inválido ou expirou.|`true`|
|audio_configuration|FACE_RECON_AUDIO_CONFIGURATION|Configura o guiamento por voz, que narra as instruções de captura em tempo real.|`FACE_RECON_AUDIO_CONFIGURATION.DISABLE`|
|onboarding_text_configuration|OnboardingTextConfiguration|Customiza os textos da tela de onboarding.|Textos padrão do SDK.|
|log_level|CAAS_LOG_LEVEL|Nível de verbosidade dos logs do SDK.|`CAAS_LOG_LEVEL.DEBUG`|

:::info **Atenção**
O campo `document_number` não dispara o registro de face — ele é utilizado somente para identificação antifraude.
:::

## OnboardingTextConfiguration

```typescript
type OnboardingTextConfiguration = {
  onboarding_title?: string;
  onboarding_first_label?: string;
  onboarding_second_label?: string;
  onboarding_third_label?: string;
};
```

| Parâmetro | Tipo | Função |
|------------|--------------|--------------|
|onboarding_title|string|Título da tela de onboarding.|
|onboarding_first_label|string|Primeira instrução exibida ao usuário.|
|onboarding_second_label|string|Segunda instrução exibida ao usuário.|
|onboarding_third_label|string|Terceira instrução exibida ao usuário.|

## Enumeradores

### CAAS_ENVIRONMENT

```typescript
enum CAAS_ENVIRONMENT {
  PRODUCTION = 'production',
  SANDBOX = 'sandbox',
}
```

### CAAS_FONT_FAMILY

```typescript
enum CAAS_FONT_FAMILY {
  JAKARTA = 'jakarta',                // apenas iOS
  FUTURA = 'futura',                  // iOS e Android
  VERDANA = 'verdana',                // iOS e Android
  TREBUCHET_MS = 'trebuchetms',       // apenas iOS
  TAMILSANGAM_MN = 'tamilsangammn',   // apenas iOS
  OPEN_SANS = 'open_sans',            // iOS e Android
  HELVETICA = 'helvetica',            // apenas Android
  POPPINS = 'poppins',                // apenas Android
  ROBOTO = 'roboto',                  // apenas Android
  SYSTEM_FONT = 'system_font',        // apenas iOS
}
```

:::info **Atenção**
A disponibilidade das fontes varia por plataforma. Caso uma fonte não suportada seja informada, a plataforma utiliza a sua fonte padrão. Para consistência entre iOS e Android, utilize `FUTURA`, `VERDANA` ou `OPEN_SANS`.
:::

### FACE_RECON_AUDIO_CONFIGURATION

```typescript
enum FACE_RECON_AUDIO_CONFIGURATION {
  ENABLE = 'enable',               // exibe o botão de áudio, com a narração iniciando desligada
  DISABLE = 'disable',             // desativa a narração e oculta o botão
  ACCESSIBILITY = 'accessibility', // exibe o botão com a narração iniciando ligada quando há recursos de acessibilidade ativos
}
```

### CAAS_LOG_LEVEL

```typescript
enum CAAS_LOG_LEVEL {
  TRACE = 'trace',
  DEBUG = 'debug',
  LOG = 'log',
  INFO = 'info',
  WARN = 'warn',
  ERROR = 'error',
}
```

---

# Instalação

URL: /documentation/caas/face_recognition/react_native/installation

## Instalando o pacote

### 1. Configurando o registro npm

Crie um arquivo `.npmrc` na raiz do seu projeto:

```sh
@qitech:registry=https://registry.npmjs.org/
//registry.npmjs.org/:_authToken=NPM_TOKEN_SENT_BY_QI_TECH
```

Substitua `NPM_TOKEN_SENT_BY_QI_TECH` pelo token fornecido pelo suporte. Caso ainda não tenha recebido o seu token, entre em contato com o suporte.caas@qitech.com.br .

### 2. Instalando a dependência

```sh
yarn add @qitech/react-native-caas
```

### 3. Importação

```javascript
import {
  CAAS_ENVIRONMENT,
  CAAS_FONT_FAMILY,
  CAAS_LOG_LEVEL,
  FACE_RECON_AUDIO_CONFIGURATION,
  FACE_RECON_ERROR,
  startFaceRecon,
} from '@qitech/react-native-caas';
```

## Configuração do Android

### 1. Repositório Maven da QI Tech

Adicione o repositório Maven da QI Tech ao `build.gradle` do projeto:

```groovy
allprojects {
  repositories {
    maven { url 'https://sdks.qitech.com.br/' }
    ...
  }
}
```

### 2. AdMob

Inicialize o serviço de AdMob adicionando o seguinte código ao `AndroidManifest.xml`:

```xml
<meta-data
  android:name="com.google.android.gms.ads.APPLICATION_ID"
  android:value="<ADMOB_APP_ID>"/>
```

Caso não possua um `ADMOB_APP_ID`, entre em contato com o suporte.caas@qitech.com.br .

## Configuração do iOS

### 1. Permissão de câmera

Adicione a entrada `NSCameraUsageDescription` ao `Info.plist` do seu aplicativo, com o motivo pelo qual o app precisa de acesso à câmera:

```xml
<key>NSCameraUsageDescription</key>
<string>Precisamos da câmera para capturar a sua selfie</string>
```

### 2. Source do repositório iOS da QI Tech

Adicione as seguintes sources no topo do seu `Podfile`:

```ruby
source 'https://cdn.cocoapods.org/'
source 'https://github.com/QITechSDKs/iOS.git'
```

### 3. Frameworks estáticos

Necessário **apenas** se você utiliza o Xcode **anterior à versão 26**:

```ruby
use_frameworks! :linkage => :static
```

:::warning Atenção
O [Flipper](https://fbflipper.com/docs/getting-started/react-native/) não funciona com `use_frameworks!`. Remova a chamada `use_flipper()` do seu `Podfile` caso ela esteja presente.
:::

### 4. Estabilidade de módulo

As dependências do Datadog exigem que o `BUILD_LIBRARY_FOR_DISTRIBUTION` esteja habilitado. Adicione o `post_install` abaixo (ou incorpore ao seu `post_install` existente):

```ruby
post_install do |installer|
  installer.pods_project.targets.each do |target|
    if ['DatadogCore', 'DatadogInternal', 'DatadogCrashReporting', 'DatadogLogs'].include?(target.name)
      target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.5'
        config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
      end
    end
  end
end
```

### 5. Instalação dos pods

```sh
cd ios && pod install
```

:::warning Atenção
Se o seu aplicativo já utiliza **Datadog**, use a versão mais recente dentro do major `3.x`. Se utiliza o **FaceDetection do MLKit**, use a versão mais recente dentro do major `8.x`.
:::

## Configuração do Expo

O pacote inclui um _config plugin_ do Expo que aplica automaticamente todas as configurações nativas de iOS e Android descritas acima. No seu `app.json`:

```json
{
  "expo": {
    "plugins": ["@qitech/react-native-caas"]
  }
}
```

Em seguida, execute o `prebuild` para aplicar as alterações nativas:

```sh
npx expo prebuild
```

---

# Introdução

URL: /documentation/caas/face_recognition/react_native/introduction

Bem vindo ao manual de integração do SDK de Reconhecimento facial da QI Tech em React Native! O módulo `@qitech/react-native-caas` expõe, por meio de uma interface TypeScript, os SDKs nativos de Android (Java/Kotlin) e iOS (Swift) da QI Tech. Você deve utilizá-lo para realizar a prova de vida (liveness) do seu cliente diretamente do seu aplicativo React Native e referenciar a imagem capturada, através de uma chave, nos demais produtos do sistema QI Tech.

## Pacotes disponíveis

| Pacote | Conteúdo | Quando usar |
|--------|----------|-------------|
|`@qitech/react-native-caas`|Reconhecimento facial, OCR e Scan de dispositivo|Quando você precisa de reconhecimento facial, OCR ou do fluxo completo de onboarding.|
|`@qitech/react-native-device-scan`|Somente Scan de dispositivo|Quando você precisa **apenas** de scan de dispositivo — instalação mais leve, com menos dependências nativas.|

:::danger Aviso Importante!
Ambos os pacotes incluem o Scan de dispositivo. **Não instale os dois** — escolha apenas um.
:::

Para o Reconhecimento facial, utilize o `@qitech/react-native-caas`.

## Problemas?

Nós não somos uma companhia que se esconde atrás de uma API! Entre em contato com o nosso [suporte](mailto:suporte.caas@qitech.com.br) e nós responderemos o mais rápido possível. Fique à vontade para nos ligar caso deseje uma resposta rápida!

### Adoramos Feedback

Mesmo que você já tenha resolvido o seu problema ou que ele seja muito simples (Até mesmo um typo ou uma organização inadequada que você já entendeu), envie-nos um e-mail, assim nós tornamos a documentação cada vez mais prática e a próxima pessoa não vai precisar sofrer as dores que você sofreu!

## Ambientes

Possuímos dois ambientes para os nossos clientes. A seleção é realizada por meio do enumerador `CAAS_ENVIRONMENT`, repassado como primeiro parâmetro da função `startFaceRecon`. No momento, os seguintes ambientes estão disponíveis:

* Produção - `CAAS_ENVIRONMENT.PRODUCTION`
* Sandbox - `CAAS_ENVIRONMENT.SANDBOX`

Cada ambiente exige uma API Key diferente para a geração do `client_session_key`.

:::danger Aviso Importante!
Não devem ser usados dados reais de pessoas físicas e/ou jurídicas nos ambientes de Sandbox da QI Tech.
:::

## Integração com Device Scan

O serviço de Reconhecimento facial realiza automaticamente uma chamada interna ao Device Scan. Por isso, o retorno de sucesso inclui o campo `device_scan_session_id`, que identifica a sessão de scan de dispositivo realizada internamente e pode ser utilizada de forma integrada em outros serviços do ecossistema QI Tech.

## Próximos passos

1. [Compatibilidade](/documentation/caas/face_recognition/react_native/compatibility) — versões mínimas de React Native, iOS e Android.
2. [Instalação](/documentation/caas/face_recognition/react_native/installation) — instalação do pacote e configuração nativa de Android, iOS e Expo.
3. [Implementação](/documentation/caas/face_recognition/react_native/example) — obtenção do `client_session_key` e exemplo completo da chamada `startFaceRecon`.
4. [O objeto FaceReconOptions](/documentation/caas/face_recognition/react_native/face_recon_options) — todos os parâmetros de customização.
5. [Coletando os Retornos](/documentation/caas/face_recognition/react_native/collecting_response) — estrutura de resposta e tratamento de erros.

---

# Coletando os Retornos do SDK

URL: /documentation/caas/face_recognition/web/collecting_response

## O método .initialize()

O método `.initialize()` é responsável pela inicialização do componente de reconhecimento facial e prova de vida. A partir de sua execução, o SDK carrega o modelo de detecção de face e valida as condições do dispositivo/navegador.

**Promise resolution:**

```javascript
{
  status: "SUCCESS",
  data: null
}
```

**Cenários de Rejection:**

- **Unsupported Browser:**

```javascript
{
  status: "FAILURE",
  reason: "UNSUPPORTED_BROWSER",
  description: "User browser is not supported."
}
```

- **Not Mobile Device:**

```javascript
{
  status: "FAILURE",
  reason: "NOT_MOBILE_DEVICE",
  description: "User device is not mobile."
}
```

- **Initialization Error:**

```javascript
{
  status: "FAILURE",
  reason: "INITIALIZATION_ERROR",
  description: "..."
}
```

## O método .open()

Este método recebe o `clientSessionKey` (obtido via chamada server-to-server) e inicia a interação com o usuário para a coleta da prova de vida. Retorna uma _Promise_ que é resolvida com a chave da imagem capturada assim que o fluxo é concluído.

**Promise resolution:**

```javascript
{
  status: "SUCCESS",
  data: string // image_key que identifica a imagem no servidor
}
```

Exemplo:

```javascript
{
  status: "SUCCESS",
  data: "d8a3b1c4-9e2f-47a5-8c3d-1b2e5..."
}
```

**Promise rejection:**

```javascript
{
  status: string;
  reason: string;
  description: string;
}
```

**Cenários de Rejection:**

- **User Canceled:**

```javascript
{
  status: "FAILURE",
  reason: "USER_CANCELED",
  description: "User pressed the back button."
}
```

- **Invalid Token:** (ocorre quando o `clientSessionKey` é inválido ou expirou)

```javascript
{
  status: "FAILURE",
  reason: "INVALID_TOKEN",
  description: "Authentication token expired or invalid"
}
```

- **Session Superseded:** (ocorre quando `.open()` é chamado novamente em uma instância já aberta)

```javascript
{
  status: "FAILURE",
  reason: "SESSION_SUPERSEDED",
  description: "A new session has been started before the previous one was completed."
}
```

---

# Implementação

URL: /documentation/caas/face_recognition/web/example

:::info Novidade na versão 4.0.0
A partir da versão **4.0.0**, o construtor `WebFaceRecon` não recebe mais o `hostComponent` — o SDK gerencia seu próprio nó DOM. O `client_session_key` continua sendo obrigatório e deve ser passado ao método `.open()`.
:::

A implementação é realizada instanciando `QITechWebFaceRecon.WebFaceRecon()`, encadeando as opções de configuração e chamando `.build()`. A inicialização ocorre em `.initialize()`, e a captura da prova de vida é iniciada com `.open(clientSessionKey)`.

## Obtendo o Client Session Key

Antes de chamar `.open()`, você deve gerar um **clientSessionKey** temporário via requisição server-to-server para a nossa API de face recognition.

### Endpoint

| Ambiente | URL |
|----------|-----|
| **Sandbox** | `https://api.sandbox.zaig.com.br/face_recognition/client_session` |
| **Produção** | `https://api.zaig.com.br/face_recognition/client_session` |

### Requisição

**Method:** `POST`

**Headers:**
```json
{
  "Authorization": "YOUR_FACE_RECON_API_KEY"
}
```

**Body (Opcional, mas recomendado):**
```json
{
  "user_id": "unique_user_identifier"
}
```

> **Importante:** O campo `user_id` é **altamente recomendado** para medidas de segurança e antifraude. Use um identificador único do usuário da sua aplicação.

### Resposta

```json
{
  "client_session_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

## Exemplo completo

```html
<script src="https://facerecon.caas.qitech.app/face-recognition-4-2-1.js"></script>

<script>
  async function iniciarReconhecimentoFacial() {
    // 1. Obtenha o clientSessionKey via chamada server-to-server
    const clientSessionKey = await fetchClientSessionKey();

    // 2. Configure e instancie o SDK
    const webFaceRecon = new QITechWebFaceRecon.WebFaceRecon()
      .setThemeConfiguration({
        primaryColor:  "#2848A8",
        tertiaryColor: "#57D9FF",
        fontFamily:    "Verdana"
      })
      .setSandboxEnvironment()
      .setSessionId("UNIQUE_SESSION_ID")
      .build();

    // 3. Inicializa (valida browser/dispositivo e carrega modelo)
    await webFaceRecon.initialize();

    // 4. Inicia a captura da prova de vida
    const response = await webFaceRecon.open(clientSessionKey);
    console.log(`Status: ${response.status}, Key: ${response.data}`);
  }
</script>
```

## Versões anteriores

:::danger Aviso Importante!
Versões anteriores à **4.0.0** recebem o `hostComponent` como primeiro argumento do construtor. A partir da **3.0.0**, o `web_token` foi removido do construtor e o fluxo de `client_session_key` foi introduzido.
:::

```html
<script>
  // Versões 3.x
  var hostComponent = document.getElementById('webfacerecon');
  var webFaceRecon = new QITechWebFaceRecon.WebFaceRecon(hostComponent)
    .setThemeConfiguration({
      "buttonColor": "#2848A8",
      "fontColor": "#FFFFFF",
      "backgroundColor": "#FFFFFF"
    })
    .setSandboxEnvironment()
    .setSessionId('UNIQUE_SESSION_ID')
    .build();

  webFaceRecon.initialize()
    .then(() => fetchClientSessionKey())
    .then(clientSessionKey => webFaceRecon.open(clientSessionKey))
    .then(response => console.log(`Status: ${response.status}, Key: ${response.data}`))
    .catch(error => {
      console.error(error);
      alert(error.reason || error);
    });
</script>
```

---

# O construtor QITechWebFaceRecon.WebFaceRecon()

URL: /documentation/caas/face_recognition/web/example_zaigwebfacerecon

O método `.WebFaceRecon()` é responsável pela configuração da instância do seu componente de reconhecimento facial. A partir da versão **4.0.0**, o construtor não recebe mais parâmetros — a renderização é gerenciada internamente pelo SDK. Utilize os métodos encadeados abaixo para personalizar o comportamento:

| Nome | Descrição | Obrigatório |
|----------|----------|----------|
| `.setSandboxEnvironment()` | Configura o ambiente para modo Sandbox. | Não |
| `.setShowInvalidTokenScreen(Boolean)` | Define se a tela de falha de autenticação deve ser exibida. Padrão: `false`. | Não |
| `.setShowBackButton(Boolean)` | Define se o botão de voltar deve ser exibido (ao ser pressionado, encerra o fluxo). Padrão: `true`. | Não |
| `.setSessionId(String)` | Define a chave que identifica a sessão iniciada no SDK — usada para rastrear o fluxo do usuário nos logs. Aceita até 255 caracteres. | Não |
| `.setThemeConfiguration(object)` | Personaliza a identidade visual do SDK. | Não |
| `.setLogLevel(String)` | Nível de verbosidade dos logs. Opções: `"info"`, `"debug"`, `"warn"`, `"error"`. Padrão: `"info"`. | Não |
| `.setCameraNotAllowedErrorDescription(String)` | Mensagem customizada exibida quando o usuário nega permissão de câmera. | Não |

O método `.setThemeConfiguration` deve receber um objeto com os seguintes campos:

| Nome | Tipo | Descrição |
| -------- | -------- | -------- |
| primaryColor | String | Hexadecimal da cor principal do SDK (fundo, header). Caso não seja informada, o padrão é `#285BB8`. |
| tertiaryColor | String | Hexadecimal da cor dos botões de ação. Caso não seja informada, o padrão é `#57D9FF`. |
| fontFamily | String | _Font Family_ a ser configurada nos textos do SDK. Caso não seja informada, será utilizada a fonte padrão do sistema. |

## Versões Anteriores

:::danger Aviso Importante!
A partir da versão **4.0.0**, o parâmetro `hostComponent` e o `web_token` no construtor foram removidos. O SDK gerencia seu próprio nó DOM internamente.
:::

Nas versões anteriores a **4.0.0**, o construtor recebia os seguintes parâmetros posicionais:

| Nome | Descrição | Obrigatório |
|----------|----------|----------|
| hostComponent | Componente HTML pai que abrigava o HTML do SDK. | Sim |
| web_token | Chave do cliente enviada pela QI Tech. | Sim (versões < 3.0.0) |

---

# Importando a biblioteca

URL: /documentation/caas/face_recognition/web/import

Para importar nossa biblioteca, adicione o endereço da nossa biblioteca em uma TAG **src** no HTML de seu website:

```html
<script src="https://facerecon.caas.qitech.app/face-recognition-4-2-1.js"></script>
```

---

# Introdução

URL: /documentation/caas/face_recognition/web/introduction

Bem vindo ao manual de integração do Web Face Recognition da QI Tech! Esta biblioteca realiza a captura de face e seu envio para a API de Face Recognition da QI Tech . Você pode utilizar esta biblioteca para capturar através do seu website uma imagem do rosto de um cliente e referenciá-lo através de uma chave nos demais produtos do sistema QI Tech.

Neste passo a passo você encontrará detalhes da biblioteca bem como um exemplo de implementação em javascript. Com isso você possui as ferramentas necessárias para poder adequar ao caso de uso da sua aplicação.

## Problemas?

Nós não somos uma companhia que se esconde atrás de uma API! Entre em contato com o nosso suporte e nós responderemos o mais rápido possível. Fique à vontade para nos ligar caso deseje uma resposta rápida!

### Adoramos Feedback

Mesmo que você já tenha resolvido o seu problema ou que ele seja muito simples (Até mesmo um typo ou uma organização inadequada que você já entendeu), envie-nos um e-mail, assim nós tornamos a documentação cada vez mais prática e a próxima pessoa não vai precisar sofrer as dores que você sofreu!

## Ambientes

Possuímos dois ambientes para os nossos clientes. 

* Produção
* Sandbox

:::danger Aviso Importante!
Não devem ser usados dados reais de pessoas físicas e/ou jurídicas nos ambientes de Sandbox da QI Tech.  
:::

A seleção é realizada por meio do método `.setSandboxEnvironment()` durante a configuração do SDK, que irá alterar o ambiente para Sandbox. Caso o método não seja chamado, o ambiente de produção será utilizado.

---

# Registro de Rosto e Validação 1:1

URL: /documentation/caas/face_recognition/web/registration_and_validation

:::danger Funcionalidade Descontinuada
Os métodos `.setDocumentNumber()` e `.setValidation()` foram descontinuados e removidos do Web Face Recognition SDK. O fluxo de registro e validação 1:1 via SDK Web não é mais suportado em nenhuma versão.

Para realizar registro e validação de face, utilize diretamente a [API de Face Recognition](https://docs.qitech.com.br/documentation/caas/face_recognition/api/face_registration).
:::