# QI Tech — Risk Solutions › Scan de dispositivo

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

Índice:
- O objeto DeviceScan (/documentation/caas/device_scan/android/device_scan_object)
- Implementação (/documentation/caas/device_scan/android/example)
- Coleta de informações (/documentation/caas/device_scan/android/information_gathering)
- Introdução (/documentation/caas/device_scan/android/introduction)
- Integração nativa (/documentation/caas/device_scan/android/native_java)
- Permissões (/documentation/caas/device_scan/android/permissions)
- Autenticação (/documentation/caas/device_scan/api/authentication)
- Compatibilidade da Biblioteca (/documentation/caas/device_scan/flutter/compatibility)
- O objeto QitechDeviceScan (/documentation/caas/device_scan/flutter/device_scan_object)
- Implementação (/documentation/caas/device_scan/flutter/example)
- Instalação (/documentation/caas/device_scan/flutter/installation)
- Introdução (/documentation/caas/device_scan/flutter/introduction)
- Permissões (/documentation/caas/device_scan/flutter/permissions)
- O objeto QITechIosDeviceScan (/documentation/caas/device_scan/ios/device_scan_object)
- Implementação (/documentation/caas/device_scan/ios/example)
- Coleta de informações (/documentation/caas/device_scan/ios/information_gathering)
- Introdução (/documentation/caas/device_scan/ios/introduction)
- Integração nativa (/documentation/caas/device_scan/ios/native_swift)
- Permissões (/documentation/caas/device_scan/ios/permissions)
- Compatibilidade (/documentation/caas/device_scan/react_native/compatibility)
- A função startDeviceScan (/documentation/caas/device_scan/react_native/device_scan_object)
- Implementação (/documentation/caas/device_scan/react_native/example)
- Instalação (/documentation/caas/device_scan/react_native/installation)
- Introdução (/documentation/caas/device_scan/react_native/introduction)
- Permissões (/documentation/caas/device_scan/react_native/permissions)
- Desktop Device Scan (/documentation/caas/device_scan/web/desktop)
- O objeto DeviceScan (/documentation/caas/device_scan/web/device_scan_object)
- Implementação (/documentation/caas/device_scan/web/example)
- Importando a biblioteca (/documentation/caas/device_scan/web/import)
- Coletando os Retornos (/documentation/caas/device_scan/web/information_gathering)
- Introdução (/documentation/caas/device_scan/web/introduction)

---

# O objeto DeviceScan

URL: /documentation/caas/device_scan/android/device_scan_object

Para utilizar a DeviceScanSDK, é necessário instanciar a classe DeviceScan. Essa instância recebe o currentContext e pode ser configurada com token/sessão, ambiente e callback (notifier).

:::danger Aviso Importante!
A partir da versão 5.0.0, o sistema de autenticação foi atualizado para usar um **token** temporário no lugar do **mobileToken**.
:::

## Versão 5.0.0+

| Parâmetro | Função | Obrigatório |
|------------|--------------|--------------|
|currentContext|Contexto da aplicação, utilizado no acesso a dados necessários. |Sim.|
|token (via .setToken(this.token))| Token de autenticação que identifica que os dados coletados são provenientes do seu aplicativo. O token é obtido por meio de requisição à API da Device Scan. |Sim.|
|sessionId (via .setSessionId(this.sessionId))|Identificador da sessão de onde os dados coletados são provenientes.|Sim.|
|notifier (via .setNotifier(this.deviceScanNotifier))|Instância de DeviceScanNotifier. Atua como callback, retornando a situação do envio (sucesso ou falha). |Não.|
|sandbox (via .setSandboxEnvironment())|Configura a biblioteca para enviar dados ao ambiente `sandbox`. Se não configurado, as requisições são enviadas para `production`. |Não.|

 **Ambiente padrão**: caso `setSandboxEnvironment()` não seja chamado, o envio é feito para `production`. 

## Versões Anteriores (até 4.x)

| Parâmetro | Função | Obrigatório |
|------------|--------------|--------------|
|currentContext|Contexto da aplicação, utilizado no acesso a dados necessários.|Sim.|
|mobileToken (via .setMobileToken(this.mobileToken))|Chave do cliente que identifica que os dados coletados são provenientes do seu aplicativo. Caso ainda não tenha recebido o seu **mobile-token**, entre em contato com o suporte: <a href='mailto:suporte.caas@qitech.com.br'>suporte.caas@qitech.com.br</a>.|Sim.|
|sessionId (via .setSessionId(this.sessionId))|Identificador da sessão de onde os dados coletados são provenientes.|Sim.|
|notifier (via .setNotifier(this.deviceScanNotifier))|Instância de DeviceScanNotifier. Atua como callback, retornando a situação do envio (sucesso ou falha).|Não.|
|sandbox (via .setSandboxEnvironment())|Configura a biblioteca para enviar dados ao ambiente `sandbox`. Se não configurado, as requisições são enviadas para `production`. |Não.|

## Resumo Rápido (Migração)
- 5.0.0+: usar `token` temporário (`setToken(this.token)`)
- < 5.0.0: usar `mobileToken` (`setMobileToken(this.mobileToken)`)
- Em ambas: `currentContext` e `sessionId` são obrigatórios. `notifier` e `sandbox` são opcionais.

---

# Implementação

URL: /documentation/caas/device_scan/android/example

:::danger Aviso Importante!
A partir da versão 5.0.0, o sistema de autenticação foi atualizado para usar um **token** dinâmico em vez de **mobileToken**. Antes de configurar o SDK, você deve gerar um **token** temporário através de uma requisição server-to-server para a nossa API de Device Scan.
:::

```java
package com.example.zaig_device_scan_sdk_test_app;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.qitech.android.devicescan.DeviceScan;
import com.qitech.android.devicescan.DeviceScanNotifier;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    private DeviceScan deviceScan;
    private DeviceScanNotifier deviceScanNotifier;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        deviceScanNotifier = new DeviceScanNotifier(this);
    }

    public void sendDeviceScan(View view) {
        try{
            deviceScan = new DeviceScan.Builder(this.getApplicationContext())
                .setToken(this.token)
                .setSessionId(this.sessionId)
                .setNotifier(this.deviceScanNotifier)
                .setSandboxEnvironment()
                .build();
        }catch (Exception ex) {
            Log.e("DeviceScan Error", "There was an error collecting DeviceScan data: " + ex.toString());
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){
        try{
            deviceScan.collectData(this.documentNumber,
                    this.eventId,
                    this.eventType);
        }catch (Exception ex) {
            Log.e("DeviceScan Error", "There was an error collecting DeviceScan data: " + ex.toString());
        }
    }

    private class ScanNotifier implements DeviceScanNotifier {
        AppCompatActivity activity;
        public ScanNotifier (AppCompatActivity myActivity){
            // Este método é customizável e pode ser utilizado para se armazenar a Activity, utilizada para operar a UI
            this.activity = myActivity;
        }

        public void onSuccess(){
            Log.i("DeviceScan", "DeviceScan successfully submitted");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // Adicionar aqui quaisquer mudanças de UI que sejam necessárias após o envio com sucesso do device scan
                }
            });
        }

        public void onError(){
            Log.i("DeviceScan", "DeviceScan submission failed");
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // Adicionar aqui quaisquer mudanças de UI que sejam necessárias após o envio com sucesso do device scan
                }
            });
        }
    }
}

```

Para utilizar o SDK do device scan android, os seguintes passos são necessários:

* Inserir as autorizações ao manifest da aplicação;
* Importar a biblioteca ao projeto da aplicação;
* Ao iniciar a aplicação, instanciar a biblioteca, passando os parâmetros adequados em seu construtor, incluindo o Notifier, responsável por dar o CallBack da operação com o resultado;
* Utilizar a função `onRequestPermissionsResult` da Activity para ser notificado do resultado da aprovação ou não das permissões requeridas;
* Requisitar as permissões ao usuário. É obrigatória a permissão de acesso a internet para o funcionamento da biblioteca;
* Ao ser notificado do resultado da aprovação ou não das permissões, colete e envie os dados por meio do método `collectData`.

---

# Coleta de informações

URL: /documentation/caas/device_scan/android/information_gathering

Para disparar a coleta e o envio de informações, é necessário (após obter as permissões do usuário) chamar o método `collectData`. O método, além de capturar as informações do dispositivo, tem como objetivo mapear a jornada do cliente dentro da aplicação. Por esse motivo, o método também aceita os campos `eventId` e `eventType`. O método possui os seguintes parâmetros:

nome | tipo | descrição
---- | ---- | ---------
documentNumber | String | O número do documento do usuário, caso disponível. (CPF/CNPJ sem pontos, traços e barra)
eventId | String | Um identificador do evento que está sendo reportado
eventType | String | Um valor enumerado que define o tipo de evento que está sendo reportado. Recomenda-se cuidado para que eventos muito similares sejam reportados com o mesmo enumerador, a fim de que inteligência possa ser construída sobre esses dados.

Após a chamada de coleta dos dados, um dos dois métodos da instância de `DeviceScanNotifier` passada no construtor da classe `DeviceScan` será chamado: `onSuccess` caso tudo corra conforme o esperado ou `onError`, em caso de erro.

---

# Introdução

URL: /documentation/caas/device_scan/android/introduction

Bem-vindo(a) ao manual de integração do Device Scan Android da QI Tech! Você deve utilizar nosso SDK para coletar informações do dispositivo e do comportamento do usuário no seu aplicativo e, assim, aumentar a assertividade das decisões.

## Problemas?

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 responderemos o mais rápido possível. Fique à vontade para nos ligar caso precise de uma resposta mais rápida!

### Adoramos Feedback

Mesmo que você já tenha resolvido o problema ou que ele seja muito simples (como um erro de digitação ou uma organização inadequada), envie-nos um e-mail. Assim, tornamos a documentação cada vez mais prática, e a próxima pessoa não precisa passar pelas mesmas dores.

## Ambientes

Disponibilizamos dois ambientes para os nossos clientes. A seleção é realizada por meio de um enumerador informado no construtor do SDK. No momento, os seguintes ambientes estão disponíveis:

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

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

---

# Integração nativa

URL: /documentation/caas/device_scan/android/native_java

Para importar nossos SDKs, é necessário realizar alterações nos arquivos build.gradle do projeto e do aplicativo.

## Adicionando ao Projeto
Adicione o endereço do nosso repositório Maven no build.gradle do projeto (no Android Studio, este arquivo aparece como “Project: \{nome_do_projeto\}”), conforme o exemplo abaixo:

```java
buildscript {
    ...
}

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

## Adicionando ao Aplicativo
Em seguida, adicione a biblioteca que você pretende importar no build.gradle do app (no Android Studio, este arquivo aparece como **“Module: \{nome_do_projeto\}.app”**), incluindo a dependência abaixo:

```java
dependencies {
    ...
    implementation 'com.qitech.android:devicescan:v6.0.0'
}
```

:::warning
Desde **abril de 2025**,** novas políticas da Google Play exigem **Android API Level 35** para que aplicativos possam ser publicados ou atualizados na Google Play Store. Por isso, recomendamos fortemente que você utilize **targetSdkVersion 35**, no mínimo.
:::

:::info
A utilização de **targetSdkVersion 35** implica na utilização do **compileSdkVersion 35**, o que acarreta 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+
:::

## Arquivo Manifest

Para utilizar o SDK, você deve adicionar a seguinte configuração ao AndroidManifest da sua aplicação:

```java
<meta-data
            android:name="com.google.android.gms.ads.AD_MANAGER_APP"
            android:value="true"/>
```

Você também deve adicionar, no mínimo, a permissão de internet, que é utilizada para enviar os dados coletados aos servidores da QI Tech:

` `

A lista de permissões deverá ser ajustada de acordo com a necessidade.

---

# Permissões

URL: /documentation/caas/device_scan/android/permissions

O SDK coleta dados do dispositivo do usuário de acordo com as permissões disponíveis no momento da coleta: quanto mais permissões o seu aplicativo solicitar e o usuário conceder, mais informações poderão ser coletadas.

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

A permissão INTERNET é obrigatória para que o SDK consiga enviar as informações aos servidores da QI Tech.
:::

## Permissões utilizadas pelo SDK

Na versão atual do SDK, as permissões abaixo podem ser utilizadas, caso estejam disponíveis:

| Permissão | Função | Obrigatória |
|------------|--------------|--------------|
|INTERNET|Envio das informações aos servidores da QI Tech.| Sim. |
|BLUETOOTH|Captura de informações do hardware de Bluetooth.| Não. |
|BLUETOOTH_CONNECT|Captura de informações de conexão Bluetooth.| Não. |
|READ_CONTACTS|Leitura da agenda de contatos.| Não. |
|ACCESS_COARSE_LOCATION|Acesso a informações de rede (Antena, operadora, etc) e à localização por este meio (menos precisa).| Não. |
|ACCESS_FINE_LOCATION|Acesso à localização por meio de GPS (mais precisa).| Não. |
|READ_PHONE_STATE|Informações de Rede, SIM, Imei e outros aspectos de telefonia.| Não. |
|QUERY_ALL_PACKAGES|Informações de aplicativos instalados no dispositivo. Necessária para devices Android 11 em diante.| Não. |

:::info **Importante**

Nosso SDK não solicita as permissões descritas. Portanto, para garantir um device scan mais completo, recomendamos solicitar e obter essas permissões antes de executar a chamada do device scan.
:::

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

A permissão QUERY_ALL_PACKAGES pode gerar atrito com o Google Play no momento do lançamento do app. Para contornar esse ponto, é possível descrever o motivo da solicitação dessa permissão.
:::

---

# Autenticação

URL: /documentation/caas/device_scan/api/authentication

:::danger Aviso Importante!
A partir da versão 5.0.0 dos SDKs de iOS e Android, o sistema de autenticação foi atualizado para usar um token temporário em vez do mobileToken.
:::

Utilizamos uma API Key para permitir o acesso à nossa API. Normalmente, essa chave é enviada por e-mail. Caso você ainda não tenha recebido a sua, envie uma mensagem para suporte.caas@qitech.com.br .

## Token temporário de autenticação

Antes de configurar o SDK, você deve gerar um token temporário por meio de uma requisição server-to-server para a nossa API.

### Gerar token

```bash
curl -X POST "https://d.viewpkg.com/device_scan/token" \
     -H "Authorization: EXAMPLE_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{ "session_id": "unique_session_identifier" }'
```

**Endpoints**

| Ambiente | URL |
|----------|-----|
| Sandbox | https://d.sandbox.viewpkg.com/device_scan/token |
| Produção | https://d.viewpkg.com/device_scan/token |

**Detalhes da Requisição**

| Campo | Tipo | Obrigatório | Descrição|
|-------|------|------------|---------|
| session_id | string | Sim | Identificador único da sessão gerado pelo seu sistema (por exemplo, UUID). |

**Request Body**
```json
{
  "session_id": "unique_session_identifier" 
}
```

**Response Body**

A resposta bem-sucedida conterá o campo `token`.
```json
{
  "token": "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6..."
}
```

:::info Atenção
Substitua `EXAMPLE_API_KEY` pela API Key recebida do suporte.
:::

---

# Compatibilidade da Biblioteca

URL: /documentation/caas/device_scan/flutter/compatibility

| Configuração | Versão mínima |
|------------|--------------|
|Flutter|3.3.0|
|Dart SDK|3.2.3|
|iOS|15.5|
|minSdkVersion (Android)|23|
|Datadog SDK nativo (iOS, trazido pelo plugin)|3.x|

---

# O objeto QitechDeviceScan

URL: /documentation/caas/device_scan/flutter/device_scan_object

:::danger Aviso Importante!
A partir da versão 1.0.0, o sistema de autenticação foi atualizado para usar um **token** temporário no lugar do **mobileToken**. O token é obtido por meio de requisição server-to-server à API da Device Scan.
:::

## Chamada

Para utilizar o plugin de Device Scan, é necessário realizar a chamada do método `startDeviceScan` que possui os seguintes parâmetros:

## Versão 1.0.0+

| Parâmetro | Tipo | Função | Obrigatório |
|------------|--------------|--------------|--------------|
|token|String|Token de autenticação temporário obtido por meio de requisição à API da Device Scan. Deve ser gerado com o mesmo `sessionId` passado a este método.|Sim.|
|environment|CaaSEnvironment|Enumerador utilizado para configurar o ambiente de execução para `sandbox` ou `production`. |Sim.|
|sessionId|String|Chave que identifica a sessão da qual os dados coletados são provenientes. **Deve ser enviado em letras minúsculas.**|Sim.|
|eventType|String|Um enumerador que define o tipo de evento sendo reportado - É pedido cuidado para que eventos muito similares seja reportados com o mesmo enumerador, a fim de que inteligência possa ser construída sobre esses dados.|Sim.|
|eventId|String|Um identificador do evento sendo reportado|Sim.|
|documentNumber|String?|O número do documento do usuário, caso disponível. (CPF/ CNPJ sem pontos, traços e barra). Pode ser omitido.|Não.|

## Versões Anteriores (até 0.x)

| Parâmetro | Tipo | Função | Obrigatório |
|------------|--------------|--------------|--------------|
|mobileToken|String|Chave do cliente que identifica que os dados coletados são provenientes do seu aplicativo. Caso ainda não tenha recebido o seu mobile-token, entre em contato com o <a href='mailto:suporte.caas@qitech.com.br'>suporte</a>.|Sim.|
|environment|CaaSEnvironment|Enumerador utilizado para configurar o ambiente de execução para `sandbox` ou `production`. |Sim.|
|sessionId|String|Chave que identifica a sessão da qual os dados coletados são provenientes. **Deve ser enviado em letras minúsculas.**|Sim.|
|eventType|String|Um enumerador que define o tipo de evento sendo reportado - É pedido cuidado para que eventos muito similares seja reportados com o mesmo enumerador, a fim de que inteligência possa ser construída sobre esses dados.|Sim.|
|eventId|String|Um identificador do evento sendo reportado|Sim.|
|documentNumber|String?|O número do documento do usuário, caso disponível. (CPF/ CNPJ sem pontos, traços e barra). Pode ser omitido.|Não.|

## Resumo Rápido (Migração)
- 1.0.0+: usar `token` temporário obtido via API (`token: token`)
- '`)
- Em ambas: `environment`, `sessionId`, `eventType` e `eventId` são obrigatórios. `documentNumber` é opcional.

## Migração para a 2.0.0
- `pubspec.yaml`: `qitech_device_scan: ^2.0.0`. O código Dart não muda.
- iOS: `source 'https://github.com/QITechSDKs/iOS.git'` no `Podfile`. O SDK nativo passa a exigir Datadog 3.x (`datadog_flutter_plugin` 3.x, se utilizado).
- Android: repositório Maven `https://sdks.qitech.com.br/` no `build.gradle`.

## Retorno

O método retorna uma String para indicar sucesso ou falha durante a coleta das informações:

### Sucesso

```javascript
Success collecting device scan data
```

### Erro

```javascript
Device Scan fail. Check token, environment and permissions
```

---

# Implementação

URL: /documentation/caas/device_scan/flutter/example

Antes de executar o exemplo abaixo, instale o plugin e aplique as configurações nativas de Android e iOS descritas em [Instalação](/documentation/caas/device_scan/flutter/installation).

## Pré-requisito para startDeviceScan

O método `startDeviceScan` requer um `token`. Este token é temporário e deve ser gerado no seu backend por meio de uma requisição server-to-server para a nossa API antes de chamar o método do SDK.

**Detalhes do Endpoint:**

- **Método:** POST
- **Path:** `/device_scan/token`
- **Sandbox URL:** `https://d.sandbox.viewpkg.com/device_scan/token`
- **Production URL:** `https://d.viewpkg.com/device_scan/token`

**Headers:**

```json
{
  "Authorization": "YOUR_DEVICE_SCAN_API_KEY"
}
```

**Body:**

```json
{
  "session_id": "unique_session_id"
}
```

A resposta bem-sucedida desta API conterá o `token` que você deve repassar ao método `startDeviceScan`.

:::note
O método de device scan pode ser executado de forma assíncrona. Portanto, não é necessário bloquear a thread principal para aguardar a resolução deste método. O usuário pode interagir normalmente com o app enquanto o device scan é processado em segundo plano.
:::

:::note
Recomendamos que o método de device scan seja executado o mais cedo possível. Como ele pode precisar de mais tempo de execução para coletar todos os dados, esta chamada antecipada é recomendada para que as informações mais completas do dispositivo sejam extraídas.
:::

---

```dart

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

final _qitechDeviceScanPlugin = QitechDeviceScan();

// Etapa 1: Gerar o token temporário via requisição server-to-server
Future<String?> fetchDeviceScanToken(String sessionId) async {
  final response = await http.post(
    Uri.parse('<DEVICE_SCAN_API_URL>'),
    headers: {
      HttpHeaders.authorizationHeader: '<API_KEY>',
      HttpHeaders.contentTypeHeader: 'application/json',
    },
    body: jsonEncode({'session_id': sessionId}),
  );

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

// Etapa 2: Inicializar o SDK com o token obtido
final sessionId = '<SESSION_ID>';
final token = await fetchDeviceScanToken(sessionId);

if (token == null) {
  print('Failed to fetch device scan token');
  return;
}

final result = await _qitechDeviceScanPlugin.startDeviceScan(
    token: token,
    environment: CaaSEnvironment.sandbox,
    sessionId: sessionId,
    eventType: '<EVENT_TYPE>',
    eventId: '<EVENT_ID>',
);

print('Device Scan result: $result');

```

---

# Instalação

URL: /documentation/caas/device_scan/flutter/installation

## Instalando o plugin

Execute o comando abaixo na raiz do seu projeto Flutter:

```bash
flutter pub add qitech_device_scan
```

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

```yaml
dependencies:
  qitech_device_scan: ^2.0.0
```

## Importação

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

E instancie o plugin:

```dart
final _qitechDeviceScanPlugin = QitechDeviceScan();
```

## Configuração do Android

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

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

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

### 2. AdMob

Inicialize o serviço de AdMob ao adicionar o seguinte código em seu `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 .

### 3. Permissões

Declare no `AndroidManifest.xml` as permissões que deseja disponibilizar ao SDK. Veja [Permissões](/documentation/caas/device_scan/flutter/permissions) para a lista completa.

## Configuração do iOS

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

Adicione a referência do repositório iOS da QI Tech em seu arquivo `Podfile`:

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

### 2. Permissões

Declare no `Info.plist` as permissões que deseja disponibilizar ao SDK. Veja [Permissões](/documentation/caas/device_scan/flutter/permissions).

### 3. Instalação das dependências

Instale as dependências diretamente através do CocoaPods:

```bash
cd ios
pod install
```

ou através do Flutter:

```bash
flutter build ios
```

:::warning Atenção
A partir da versão **2.0.0**, o SDK nativo de iOS exige o Datadog `3.x`. Se o seu aplicativo já utiliza o `datadog_flutter_plugin`, use a versão mais recente dentro do major `3.x`.
:::

---

# Introdução

URL: /documentation/caas/device_scan/flutter/introduction

Bem vindo ao manual de integração da Device Scan da QI Tech em Flutter! Você deve utilizar o nosso Plugin para coletar informações do celular e do comportamento do usuário em seu aplicativo e assim melhorar a assertividade das decisões.

## Plugins disponíveis

| Plugin | Conteúdo | Quando usar |
|--------|----------|-------------|
|`qitech_device_scan`|Somente Scan de dispositivo|Quando você precisa **apenas** de scan de dispositivo — instalação mais leve, com menos dependências nativas.|
|`flutter_kyc_qitech`|Reconhecimento facial, OCR e Scan de dispositivo|Quando você também precisa de reconhecimento facial ou OCR.|

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

Esta seção documenta o `qitech_device_scan`. Se o seu aplicativo utiliza o `flutter_kyc_qitech`, consulte a seção [Flutter do Reconhecimento facial](/documentation/caas/face_recognition/flutter/introduction) ou [Flutter do OCR](/documentation/caas/ocr/flutter/introduction) — naquele plugin, o método `startDeviceScan` recebe parâmetros posicionais em vez de nomeados.

## 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 de enumerador repassado no parâmetro da chamada do plugin, no momento, os seguintes ambientes estão disponíveis:

* Produção - `production`
* Sandbox - `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.  
:::

---

# Permissões

URL: /documentation/caas/device_scan/flutter/permissions

O plugin coleta dados do dispositivo do usuário conforme as permissões que estão disponíveis no momento da coleta: conforme mais permissões seu aplicativo requerir e o usuário disponibilizar, mais informações são coletadas do dispositivo do usuário.

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

A permissão de INTERNET é obrigatória para que o SDK consiga enviar as informações aos servidores da QI Tech.
:::

## Permissões utilizadas pelo plugin

:::info **Importante**

Nosso plugin não solicita as permissões descritas. Portanto, para garantir um scan de dipositivo mais completo, recomendamos a coleta dessas permissões antes de executar a chamada da device scan.
:::

### Android

Para a plataforma android, as seguintes permissões são utilizadas caso estejam disponíveis:

| Permissão | Função | Obrigatória |
|------------|--------------|--------------|
|INTERNET|Obrigatória, para envio das informações aos servidores da QI Tech.| Sim. |
|BLUETOOTH|Captura de informações do hardware de Bluetooth.| Não. |
|BLUETOOTH_CONNECT|Captura de informações de conexão Bluetooth.| Não. |
|READ_CONTACTS|Leitura da agenda de contatos.| Não. |
|ACCESS_COARSE_LOCATION|Acesso a informações de rede (Antena, operadora...) e à localização por este meio (Menos preciso).| Não. |
|ACCESS_FINE_LOCATION|Acesso à localização por meio de GPS (Mais preciso).| Não. |
|READ_PHONE_STATE|Informações de Rede, SIM, Imei e outros aspectos de telefonia.| Não. |
|QUERY_ALL_PACKAGES|Informações de aplicativos instalados no dispositivo. Necessária para devices Android 11 em diante.| Não. |

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

A permissão de QUERY_ALL_PACKAGES pode gerar atrito com o Google Play no momento do lançamento do App. Para solucioná-lo é possível descrever o motivo da solicitação da permissão.
:::

### iOS

Para a plataforma iOS, as seguintes permissões são utilizadas caso estejam disponíveis:

* location - Captura de dados de geolocalização do device

#### Arquivo Info.plist

O primeiro passo para disponibilizar permissões para o plugin é configurar a permissão no arquivo Info.plist da aplicação, utilizando a seguinte linha de código para cada uma das permissões desejadas:

* location - Captura de dados de geolocalização do device:

` NSLocationWhenInUseUsageDescription `
` Adicionar a mensagem que você deseja que apareça para o usuário quando o iOS solicitar a permissão de acesso à geolocalização `

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

Para melhorar a experiência do usuário no momento da solicitação das permissões você deve personalizar a mensagem reproduzida no pop-up de solicitação conforme descrito anteriormente.
:::

---

# O objeto QITechIosDeviceScan

URL: /documentation/caas/device_scan/ios/device_scan_object

Para utilizar o DeviceScan iOS da QI Tech, é necessário importar o framework QITechIosDeviceScan e então instanciar a classe QITechIosDeviceScan que possui os seguintes parâmetros no construtor:

:::danger Aviso Importante!
A partir da versão 5.0.0, o sistema de autenticação foi atualizado para usar um **token**  temporário em vez de **mobileToken**.
:::

## Versão 5.0.0+

nome | tipo | descrição
---- | ----- | ------
environment | String | Um enumerador do ambiente onde a aplicação está sendo executada - `sandbox` ou `production` - caso um valor diferente seja enviado, uma exceção será gerada **obrigatório**
token | String | Token de autenticação que identifica que os dados coletados são provenientes do seu aplicativo. Obtida através de requisição à API da Device Scan. **obrigatório**
sessionId | String | O identificador da sessão (**Deve ser o mesmo utilizado para gerar o token**), que será enviado também no momento da avaliação do evento (Transação, Onboarding, por exemplo), para cruzamento entre os dados do device scan e o evento a ser avaliado. **obrigatório**

## Versões Anteriores

nome | tipo | descrição
---- | ----- | ------
environment | String | Um enumerador do ambiente onde a aplicação está sendo executada - `sandbox` ou `production` - caso um valor diferente seja enviado, uma exceção será gerada **obrigatório**
mobileToken | String | A chave de cliente enviada pelo suporte da QI Tech e que identifica que os dados coletados são provenientes do seu aplicativo. Por questões de segurança, caso esta chave esteja incorreta, os servidores da QI Tech recebem mas não processam a chamada. **obrigatório**
sessionId | String | O identificador da sessão, que será enviado também no momento da avaliação do evento (Transação, Onboarding, por exemplo), para cruzamento entre os dados do device scan e o evento a ser avaliado. **obrigatório**

---

# Implementação

URL: /documentation/caas/device_scan/ios/example

:::danger Aviso Importante!
A partir da versão 5.0.0, o sistema de autenticação foi atualizado para usar um **token** dinâmico em vez de **mobileToken**. Antes de configurar o SDK, você deve gerar um **token** temporário através de uma requisição server-to-server para a nossa API de Device Scan.
:::

```swift
import UIKit
import QITechIosDeviceScan

class ViewController: UIViewController {

    var qitechDeviceScan : QITechIosDeviceScan?

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

    func setupDeviceScan() -> Void
    {
        // The environment can be 'sandbox' ou 'production'
        let environment = "sandbox"

        // MobileToken is the key sent to you by QI Tech. Each environment requires a different MobileToken.
        let token = "TEMPORARY_TOKEN_FROM_DEVICE_SCAN_API"

        // You must send the same session id in the moment of using the device scan and event analysis. It must be a key that uniquely identifies each user session in the app
        let sessionId = "62715840-068a-4ded-a4e2-a1ec83f857d4"

        do{
            self.qitechDeviceScan = try QITechIosDeviceScan(environment: environment, token: token, sessionId: sessionId)
        }
        catch{
            print ("Error found when instantiating QITech's DeviceScan")
        }

        let permissions = ["location"]

        do{
            try self.qitechDeviceScan?.requestPermissions(permissions: permissions)
        }
        catch{
            print ("Error found when requesting QITech's DeviceScan's permissions")
        }
    }

    func onSuccess()
    {
        // Do something if QI Tech DeviceScan's collectData method succesfully collected device data
    }

    func onError()
    {
        // Do something if QI Tech DeviceScan's collectData method found any error when collecting device data
    }

    func collectQITechDeviceScanData()
    {
        // If you have your customer's document number (CPF or CNPJ without dots, hyphen or slash), you must sent it to QI Tech
        let documentNumber = "12345678900"

        // EventType must represent with type of interation the user had with your app on the moment that collectData method was called
        let eventType = "login"

        // EventId is your code that identifies the event sent to QI Tech
        let eventId = "7038632032"

        do{
            try self.qitechDeviceScan?.collectData(documentNumber: documentNumber, eventId: eventId, eventType: eventType, onSuccessHandler: self.onSuccess, onErrorHandler: self.onError)
        }
        catch{
            print("Error found when collecting QITech's DeviceScan data")
        }
    }
}
```

Para utilizar o SDK do Device Scan iOS, os seguintes passos são necessários:

Inserir as autorizações no arquivo Info.plist
Adicionar o framework ao projeto do aplicativo
Ao iniciar a aplicação, instanciar a biblioteca, passando os parâmetros adequados
Caso sua aplicação ainda não tenha solicitado as permissões ao usuário, requisitar as permissões ao usuário por meio da função `requestPermissions` do objeto previamente instanciado
Coletar e enviar os dados por meio do método `collectData`

---

# Coleta de informações

URL: /documentation/caas/device_scan/ios/information_gathering

Para disparar a coleta e o envio de informações, é necessário chamar o método `collectData`. O método, além de capturar as informações do dispositivo, tem como objetivo mapear a jornada do cliente dentro da aplicação. É por esta razão que o método também aceita os campos `eventId` e `eventType`. Outro ponto importante é que o método envia as informações para o servidor da QI Tech via request http assíncrono, e para isso, a notificação de sucesso ou erro da requisição é feita através de Completion Handlers. O método possui os seguintes parâmetros:

nome | tipo | descrição
---- | ---- | ---------
documentNumber | String | O número do documento do usuário, caso disponível. (CPF/ CNPJ sem pontos, traços e barra)
eventId | String | Um identificador do evento sendo reportado
eventType | String | Um enumerador que define o tipo de evento sendo reportado (Exemplo: 'login') - Cuidado para que eventos muito similares sejam reportados com o mesmo enumerador, a fim de que inteligência possa ser construída sobre esses dados
onSuccessHandler | func() &#8209;> Void | Função que será chamada no caso de sucesso no envio dos dados para o servidor da QI Tech **obrigatório**
onErrorHandler | func() &#8209;> Void | Função que será chamada no caso de erro no envio dos dados para o servidor da QI Tech **obrigatório**

---

# Introdução

URL: /documentation/caas/device_scan/ios/introduction

Bem vindo ao manual de integração do Device Scan iOS da QI Tech! Você deve utilizar o nosso Framework para coletar informações do celular e do comportamento do usuário em seu aplicativo e assim melhorar a assertividade das decisões.

## 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 de enumerador repassado no construtor da classe QITechIosDeviceScan, no momento, os seguintes ambientes estão disponíveis:

* Produção - `production`
* Sandbox - `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.  
:::

---

# Integração nativa

URL: /documentation/caas/device_scan/ios/native_swift

## Remotamente

> Iniciando a instalação

```shell
  pod init
```

Nosso SDK pode ser importado utilizando CocoaPods.

SDK | Versão atual
---- | -----
QITechIosDeviceScan | `pod 'QITechIosDeviceScan', '~> 6.0.0'`

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

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

> Adicionando a source na podfile

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

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

> Adicionando o pod na podfile

```ruby
  pod 'QITechIosDeviceScan', '~> <version>'
```
Por fim, basta adicionar o nome do `pod` de acordo com o formato acima.

:::danger Atenção: 
Mudança de Arquitetura (v5.0.0+) A partir da versão 5.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 5.0.0 ou superior)

```ruby
  source 'https://github.com/QITechSDKs/iOS.git'
  target 'ExampleApp' do
    use_frameworks! :linkage => :static
    pod 'QITechIosDeviceScan', '~> 6.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
```

> Exemplo de podfile (Versões Anteriores)

```ruby
  source 'https://github.com/QITechSDKs/iOS.git'
  target 'ExampleApp' do
    use_frameworks!
    pod 'QITechIosDeviceScan', '~> 2.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
```

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

É necessário habilitar a estabilidade do módulo para a dependência de monitoramento 'Datadog'. Para evitar possíveis problemas de compilação para diferentes versões do swift. Portanto, adicione o bloco descrito no post_install do seu arquivo Podfile (ou inclua-o no bloco post_install existente, caso já tenha um)
:::

:::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 dependencias

```shell
  pod install
```

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

---

# Permissões

URL: /documentation/caas/device_scan/ios/permissions

A SDK coleta dados do dispositivo e, de acordo com o funcionamento do sistema operacional iOS, necessita de permissões específicas para cada dado a ser coletado. De maneira a oferecer uma experiência customizada para os usuários da aplicação que possua o SDK embarcado, implementamos um mecanismo que utiliza os parâmetros passados pelo desenvolvedor para solicitar as permissões ao usuário, seguindo a seguinte mecânica:

As permissões que forem enviadas como parâmetro do método `requestPermissions`, no formato de String, são solicitadas ao usuário - a menos que já tenham sido solicitadas anteriormente.
O usuário, por meio de uma caixa de diálogo disponibilizada pelo próprio sistema operacional, é questionado sobre as permissões consideradas necessárias pelo framework.
As permissões são então concedidas ou negadas e, no momento que o método `collectData`, este coletará apenas os dados cuja permissão foi concedida.

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

Caso seu aplicativo já tenha solicitado as permissões necessárias, não é necessário chamar novamente o método `requestPermissions`, o SDK irá herdar as permissões solicitadas pelo aplicativo.
:::

## Permissões utilizadas pelo SDK

Na versão atual do SDK, as seguintes permissões são utilizadas caso estejam disponíveis:

* location - Captura de dados de geolocalização do device

## Arquivo Info.plist

O primeiro passo para disponibilizar permissões para o SDK é configurar a permissão no arquivo Info.plist da aplicação, utilizando a seguinte linha de código para cada uma das permissões desejadas:

* location - Captura de dados de geolocalização do device:

` NSLocationWhenInUseUsageDescription `
` Adicionar a mensagem que você deseja que apareça para o usuário quando o iOS solicitar a permissão de acesso à geolocalização `

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

Para melhorar a experiência do usuário no momento da solicitação das permissões você deve personalizar a mensagem reproduzida no pop-up de solicitação conforme descrito anteriormente.
:::

---

# Compatibilidade

URL: /documentation/caas/device_scan/react_native/compatibility

O módulo `@qitech/react-native-device-scan` 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|

## Versão atual do pacote

| Pacote | Versão |
|--------|--------|
|`@qitech/react-native-device-scan`|`1.2.0`|
|`@qitech/react-native-caas`|`11.3.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/device_scan/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`.
:::

---

# A função startDeviceScan

URL: /documentation/caas/device_scan/react_native/device_scan_object

## Chamada

Para utilizar o módulo de Device Scan, é necessário realizar a chamada da função `startDeviceScan`, que possui os seguintes parâmetros **posicionais**:

```javascript
await startDeviceScan(
  token,
  document_number,
  session_id,
  event_id,
  event_type,
  environment
);
```

| Parâmetro | Tipo | Função | Obrigatório |
|------------|--------------|--------------|--------------|
|token|string|Token de autenticação temporário obtido por meio de requisição server-to-server à API de Device Scan. Deve ser gerado com o mesmo `session_id` passado a esta função.|Sim.|
|document_number|string|O número do documento do usuário (CPF/CNPJ sem pontos, traços e barra).|Sim.|
|session_id|string|Chave que identifica a sessão da qual os dados coletados são provenientes. **Deve ser enviada em letras minúsculas.**|Sim.|
|event_id|string|Um identificador do evento sendo reportado.|Sim.|
|event_type|string|Um enumerador que define o tipo de evento sendo reportado (ex.: `'onboarding'`). É pedido cuidado para que eventos muito similares sejam reportados com o mesmo enumerador, a fim de que inteligência possa ser construída sobre esses dados.|Sim.|
|environment|CAAS_ENVIRONMENT|Enumerador utilizado para configurar o ambiente de execução para `SANDBOX` ou `PRODUCTION`.|Sim.|

:::warning Atenção
A ordem dos parâmetros importa. Note que `session_id` vem **antes** de `event_id` e `event_type` na assinatura da função, mesmo que internamente o módulo nativo receba os valores em outra ordem.
:::

## CAAS_ENVIRONMENT

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

## Retorno

A função retorna uma `Promise` resolvida com uma string indicando o sucesso da coleta.

### Sucesso

```javascript
Success collecting device scan data
```

### Erro

A _Promise_ é rejeitada quando a coleta falha:

```javascript
There was an error collecting DeviceScan data
```

Quando o módulo nativo não está corretamente vinculado, a chamada lança:

```javascript
The package '@qitech/react-native-device-scan' doesn't seem to be linked. Make sure:

- You have run 'pod install'
- You rebuilt the app after installing the package
- You are not using Expo managed workflow
```

## Exemplo

```tsx
try {
  const result = await startDeviceScan(
    token,
    '<CPF_NUMBER>',
    '<SESSION_ID>',
    '1',
    'onboarding',
    CAAS_ENVIRONMENT.SANDBOX
  );

  console.log(result); // "Success collecting device scan data"
} catch (error) {
  console.log('Error executing device scan: ' + error);
}
```

## Utilizando o pacote completo

Se o seu aplicativo utiliza o `@qitech/react-native-caas`, a função `startDeviceScan` tem exatamente a mesma assinatura e o mesmo comportamento — apenas o caminho do `import` muda:

```javascript
import { CAAS_ENVIRONMENT, startDeviceScan } from '@qitech/react-native-caas';
```

---

# Implementação

URL: /documentation/caas/device_scan/react_native/example

## Pré-requisito: obtendo o token

A função `startDeviceScan` exige um `token`. Esse token é temporário e deve ser gerado 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://d.sandbox.viewpkg.com/device_scan/token` |
| **Produção** | `https://d.viewpkg.com/device_scan/token` |

### Requisição

**Method:** `POST`

**Headers:**

```json
{
  "Authorization": "YOUR_DEVICE_SCAN_API_KEY"
}
```

**Body:**

```json
{
  "session_id": "unique_session_id"
}
```

### Resposta

A resposta bem-sucedida conterá o `token` que deve ser repassado à função `startDeviceScan`.

```json
{
  "token": "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6..."
}
```

:::danger Aviso Importante!
A API Key de Device Scan nunca deve ser embarcada no aplicativo. A requisição acima deve partir exclusivamente do seu backend. O `session_id` usado para gerar o token deve ser **o mesmo** repassado à função `startDeviceScan`.
:::

:::note
O device scan pode ser executado de forma assíncrona. Portanto, não é necessário bloquear a interface para aguardar a resolução da _Promise_. O usuário pode interagir normalmente com o app enquanto o device scan é processado em segundo plano.
:::

:::note
Recomendamos que o device scan seja executado o mais cedo possível — por exemplo, dentro de um `useEffect`. Como ele pode precisar de mais tempo de execução para coletar todos os dados, essa chamada antecipada garante que as informações mais completas do dispositivo sejam extraídas.
:::

## Assinatura da função

```javascript
await startDeviceScan(
  token,            // string - token obtido na API
  document_number,  // string - CPF do usuário
  session_id,       // string - identificador da sessão
  event_id,         // string - identificador do evento
  event_type,       // string - tipo do evento (ex.: 'onboarding')
  environment       // CAAS_ENVIRONMENT.SANDBOX ou CAAS_ENVIRONMENT.PRODUCTION
);
```

Veja [A função startDeviceScan](/documentation/caas/device_scan/react_native/device_scan_object) para a descrição completa de cada parâmetro.

## Exemplo completo

```tsx
import * as React from 'react';
import { useCallback, useEffect } from 'react';
import { View, Button, Platform, PermissionsAndroid, Permission } from 'react-native';
import { request, PERMISSIONS, RESULTS } from 'react-native-permissions';
import { CAAS_ENVIRONMENT, startDeviceScan } from '@qitech/react-native-device-scan';

const DEVICE_SCAN_API_URL = 'https://d.sandbox.viewpkg.com/device_scan/token';
const DEVICE_SCAN_API_KEY = '<DEVICE_SCAN_API_KEY>';

const config = {
  environment: CAAS_ENVIRONMENT.SANDBOX,
  sessionId: '<SESSION_ID>',
  documentNumber: '<CPF_NUMBER>',
  deviceScanEventId: '1',
  deviceScanEventType: 'onboarding',
};

export default function App() {
  // Etapa 1: solicitar as permissões que ampliam a coleta
  const requestDeviceScanPermissions = async (): Promise<boolean> => {
    if (Platform.OS === 'ios') {
      const result = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
      return result === RESULTS.GRANTED;
    }

    const permissionsToRequest: Permission[] = [
      PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
      PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
      PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE,
      PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
    ];

    // BLUETOOTH_CONNECT só é necessária no Android 12+ (API 31+)
    if (Platform.Version >= 31) {
      permissionsToRequest.push('android.permission.BLUETOOTH_CONNECT' as Permission);
    }

    const results = await PermissionsAndroid.requestMultiple(permissionsToRequest);

    return (
      results[PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION] ===
        PermissionsAndroid.RESULTS.GRANTED ||
      results[PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION] ===
        PermissionsAndroid.RESULTS.GRANTED
    );
  };

  // Etapa 2: obter o token por meio do seu backend
  const fetchDeviceScanToken = useCallback(async () => {
    const response = await fetch(DEVICE_SCAN_API_URL, {
      method: 'POST',
      headers: {
        'Authorization': DEVICE_SCAN_API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ session_id: config.sessionId }),
    });

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

    const data = await response.json();

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

    return data.token;
  }, []);

  // Etapa 3: executar a coleta
  const captureDeviceScan = async (): Promise<void> => {
    try {
      const deviceScanToken = await fetchDeviceScanToken();

      const result = await startDeviceScan(
        deviceScanToken,
        config.documentNumber,
        config.sessionId,
        config.deviceScanEventId,
        config.deviceScanEventType,
        config.environment
      );

      console.log('Device Scan result: ' + String(result));
    } catch (error) {
      console.log('Error executing device scan: ' + error);
    }
  };

  useEffect(() => {
    const init = async () => {
      await requestDeviceScanPermissions();
      await captureDeviceScan();
    };
    init();
  }, []);

  return (
    <View>
      <Button title="Executar Device Scan" onPress={captureDeviceScan} />
    </View>
  );
}
```

## Boas práticas

* Execute o device scan **o mais cedo possível** (por exemplo, em um `useEffect`) — ele precisa de tempo para coletar os dados completos do dispositivo.
* O device scan é **assíncrono** e não bloqueia a interface. Não é necessário aguardar a resolução da _Promise_ para prosseguir com os demais fluxos.
* Solicite as permissões **antes** de chamar `startDeviceScan`. O SDK não solicita permissões por conta própria — ele apenas coleta o que já foi concedido.

## 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_ds.tsx` demonstra o uso do Scan de dispositivo com o `@qitech/react-native-device-scan`. Substitua as API Keys de exemplo pelas suas credenciais. Caso ainda não as tenha recebido, entre em contato com o suporte.caas@qitech.com.br .

---

# Instalação

URL: /documentation/caas/device_scan/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-device-scan
```

### 3. Importação

```javascript
import {
  CAAS_ENVIRONMENT,
  startDeviceScan,
} from '@qitech/react-native-device-scan';
```

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

### 3. Permissões

Declare no `AndroidManifest.xml` as permissões que deseja disponibilizar ao SDK. Veja [Permissões](/documentation/caas/device_scan/react_native/permissions) para a lista completa.

## Configuração do iOS

### 1. 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'
```

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

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

### 4. Permissões

Declare no `Info.plist` as permissões que deseja disponibilizar ao SDK. Veja [Permissões](/documentation/caas/device_scan/react_native/permissions).

### 5. Instalação dos pods

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

## 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-device-scan"]
  }
}
```

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

```sh
npx expo prebuild
```

---

# Introdução

URL: /documentation/caas/device_scan/react_native/introduction

Bem vindo ao manual de integração do Device Scan da QI Tech em React Native! O módulo `@qitech/react-native-device-scan` 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 coletar informações do celular e do comportamento do usuário em seu aplicativo e assim melhorar a assertividade das decisões.

## Pacotes disponíveis

| Pacote | Conteúdo | Quando usar |
|--------|----------|-------------|
|`@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.|
|`@qitech/react-native-caas`|Reconhecimento facial, OCR e Scan de dispositivo|Quando você também precisa de reconhecimento facial ou OCR.|

:::danger Aviso Importante!
Ambos os pacotes incluem o Scan de dispositivo e expõem a mesma função `startDeviceScan`, com a mesma assinatura. **Não instale os dois** — escolha apenas um.
:::

Esta seção documenta o `@qitech/react-native-device-scan`. Se o seu aplicativo já utiliza o `@qitech/react-native-caas`, basta trocar o caminho do `import` — todo o restante desta documentação se aplica sem alterações.

## 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 último parâmetro da função `startDeviceScan`. 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 token.

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

## Próximos passos

1. [Compatibilidade](/documentation/caas/device_scan/react_native/compatibility) — versões mínimas de React Native, iOS e Android.
2. [Instalação](/documentation/caas/device_scan/react_native/installation) — instalação do pacote e configuração nativa de Android, iOS e Expo.
3. [Implementação](/documentation/caas/device_scan/react_native/example) — obtenção do token e exemplo completo da chamada `startDeviceScan`.
4. [A função startDeviceScan](/documentation/caas/device_scan/react_native/device_scan_object) — parâmetros e retorno.
5. [Permissões](/documentation/caas/device_scan/react_native/permissions) — permissões que ampliam a coleta de dados.

---

# Permissões

URL: /documentation/caas/device_scan/react_native/permissions

O módulo coleta dados do dispositivo do usuário conforme as permissões que estão disponíveis no momento da coleta: conforme mais permissões seu aplicativo requerir e o usuário disponibilizar, mais informações são coletadas do dispositivo do usuário.

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

A permissão de INTERNET é obrigatória para que o SDK consiga enviar as informações aos servidores da QI Tech.
:::

:::info **Importante**

Nosso módulo não solicita as permissões descritas. Portanto, para garantir um scan de dispositivo mais completo, recomendamos a coleta dessas permissões antes de executar a chamada de `startDeviceScan`.
:::

## Android

Para a plataforma Android, as seguintes permissões são utilizadas caso estejam disponíveis:

| Permissão | Função | Obrigatória |
|------------|--------------|--------------|
|INTERNET|Obrigatória, para envio das informações aos servidores da QI Tech.| Sim. |
|BLUETOOTH|Captura de informações do hardware de Bluetooth.| Não. |
|BLUETOOTH_CONNECT|Captura de informações de conexão Bluetooth. Necessária a partir do Android 12 (API 31).| Não. |
|READ_CONTACTS|Leitura da agenda de contatos.| Não. |
|ACCESS_COARSE_LOCATION|Acesso a informações de rede (Antena, operadora...) e à localização por este meio (Menos preciso).| Não. |
|ACCESS_FINE_LOCATION|Acesso à localização por meio de GPS (Mais preciso).| Não. |
|READ_PHONE_STATE|Informações de Rede, SIM, Imei e outros aspectos de telefonia.| Não. |
|QUERY_ALL_PACKAGES|Informações de aplicativos instalados no dispositivo. Necessária para devices Android 11 em diante.| Não. |

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

A permissão de QUERY_ALL_PACKAGES pode gerar atrito com o Google Play no momento do lançamento do App. Para solucioná-lo é possível descrever o motivo da solicitação da permissão.
:::

### Solicitando as permissões

```tsx
import { Platform, PermissionsAndroid, Permission } from 'react-native';

const permissionsToRequest: Permission[] = [
  PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
  PermissionsAndroid.PERMISSIONS.ACCESS_COARSE_LOCATION,
  PermissionsAndroid.PERMISSIONS.READ_PHONE_STATE,
  PermissionsAndroid.PERMISSIONS.READ_CONTACTS,
];

// BLUETOOTH_CONNECT só é necessária no Android 12+ (API 31+)
if (Platform.Version >= 31) {
  permissionsToRequest.push('android.permission.BLUETOOTH_CONNECT' as Permission);
}

const results = await PermissionsAndroid.requestMultiple(permissionsToRequest);
```

## iOS

Para a plataforma iOS, a seguinte permissão é utilizada caso esteja disponível:

* location - Captura de dados de geolocalização do device

### Arquivo Info.plist

O primeiro passo para disponibilizar permissões para o módulo é configurar a permissão no arquivo `Info.plist` da aplicação:

```xml
<key>NSLocationWhenInUseUsageDescription</key>
<string>Adicionar a mensagem que você deseja que apareça para o usuário quando o iOS solicitar a permissão de acesso à geolocalização</string>
```

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

Para melhorar a experiência do usuário no momento da solicitação das permissões você deve personalizar a mensagem reproduzida no pop-up de solicitação conforme descrito anteriormente.
:::

### Solicitando as permissões

```tsx
import { request, PERMISSIONS, RESULTS } from 'react-native-permissions';

const result = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);

if (result === RESULTS.GRANTED) {
  // permissão concedida
}
```

## Coleta de informações

Para a lista completa das informações coletadas em cada plataforma, consulte as páginas de coleta dos SDKs nativos:

* [Coleta de informações — Android](/documentation/caas/device_scan/android/information_gathering)
* [Coleta de informações — iOS](/documentation/caas/device_scan/ios/information_gathering)

---

# Desktop Device Scan

URL: /documentation/caas/device_scan/web/desktop

Este é o **Desktop Device Scan**, nosso módulo *white label* complementar à **Web Device Scan**. Você pode utilizar nosso programa para coletar informações profundas do dispositivo, além de identificar a presença de softwares maliciosos!

Este software foi desenvolvido para atender à [Instrução Normativa BCB nº 491](https://www.bcb.gov.br/estabilidadefinanceira/exibenormativo?tipo=Instru%C3%A7%C3%A3o%20Normativa%20BCB&numero=491). Ele, em conjunto com a Web Device Scan, é capaz de gerar uma **identificação única e confiável** para cada dispositivo!

:::warning Atenção
Nosso aplicativo é *White Label*! Você pode utilizar seus próprios logotipos no instalador, além de personalizar o nome do executável e as mensagens exibidas, deixando a experiência mais amigável para o seu usuário.
:::

## Utilização

Neste passo a passo, você encontrará detalhes sobre a utilização do programa em conjunto com a biblioteca, bem como um exemplo de implementação em JavaScript. Com isso, você terá as ferramentas necessárias para adaptar a solução ao seu caso de uso.

```html
<html>
<head>
    <script src="https://ds.viewpkg.com/device-scan-2-1-1.js"></script>
</head>

<script>
    var deviceScan = new vPkg.DeviceScan('web_token', 'session_id')
    deviceScan.setSandbox()
    deviceScan.setDesktop(true)
    deviceScan.info('event_type', 'event_id')
        .then((res) => console.log(res))
        .catch((error) => console.log(error))
</script>
</html>
```

Ao utilizar a flag `deviceScan.setDesktop(true)`, o SDK web tentará identificar a presença do aplicativo instalado. Caso ele não esteja instalado ou apresente problemas, você poderá receber um dos seguintes erros:

| Erro                        | Descrição                                                                                                                                                                                         |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Timeout in Secure App**   | O aplicativo está presente, mas não está respondendo corretamente. Reinstale o aplicativo para corrigir o problema.                                                                               |
| **Invalid desktop data**    | O aplicativo foi modificado ou corrompido. Reinstale o aplicativo para restaurar a integridade.                                                                                                   |
| **Desktop App Not Present** | O aplicativo não está instalado. Ofereça o link de download fornecido pela QI Tech ao usuário.                                                                                                    |
| **Unexpected App Error**    | Um erro inesperado ocorreu na comunicação com o aplicativo. Se o problema persistir após a reinstalação, entre em contato com o suporte: <a href='mailto:suporte.caas@qitech.com.br'>suporte</a>. |

## Sistemas Operacionais Suportados

O **Desktop Device Scan** está disponível para os principais sistemas operacionais modernos, oferecendo compatibilidade nativa e desempenho otimizado em cada plataforma.

Windows 10/11 x64
macOS Intel (x86_64)
macOS Apple Silicon (M1/M2/M3)

---

# O objeto DeviceScan

URL: /documentation/caas/device_scan/web/device_scan_object

Para utilizar serviço de scan de dispositivo, é necessário instanciar a classe DeviceScan que possui os seguintes parâmetros no construtor:

| Parâmetro | Função | Obrigatório |
|------------|--------------|--------------|
|.setSandbox()|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.|
|.setGeoLocation(true)|Caso este parâmetro seja definido como `true`, a biblioteca irá solicitar a permissão de coleta dos dados de GPS. Caso ausente ou definido como `false`, as informações de geo localização não são extraídas.|Não.|

:::info **Atenção**
Se o usuário negar o acesso aos dados de localização, a biblioteca será executada normalmente, mas sem coletar essas informações.
:::

## A função deviceScan.info()

Para executar a função de análise de dados do seu usuário, é necessário enviar os seguintes parâmetros para a biblioteca que identificarão sua empresa e a sessão de usuário a qual as informações pertencem. Além disso, os argumentos event_id e event_type, apesar de serem opcionais, nos auxiliam a indenfiticar o padrão de navegação do usuário em sua página, e com isso, evitar ainda mais fraudes.

Abaixo temos o detalhamento de cada um dos argumentos:

Nome | Tipo | Descrição
---- | ---- | ---------
web_token | String | Chave do cliente que identifica que os dados coletados são provenientes do seu aplicativo. Caso ainda não tenha recebido o seu web-token, entre em contato com o suporte . **obrigatório**
session_id | String | Chave que identifica a sessão da qual os dados coletados são provenientes. **obrigatório**
event_id | String | Um identificador do evento sendo reportado
event_type | String | Um enumerador que define o tipo de evento sendo reportado - É pedido cuidado para que eventos muito similares seja reportados com o mesmo enumerador, a fim de que inteligência possa ser construída sobre esses dados.

## Exemplo de Implementação
Um exemplo simples de implementação pode ser visto abaixo:

```html
   html>
    <head>
        <script src="https://ds.viewpkg.com/device-scan-2-1-1.js"></script>
    </head>

    <script>
        var deviceScan = new vPkg.DeviceScan('web_token', 'session_id')
        deviceScan.setSandbox()
        deviceScan.setGeoLocation(true)
        async function callDeviceScan(eventType, eventId) {
            await deviceScan.info(eventType, eventId)
            .then((res) => console.log(res))
            .catch((error) => console.log(error))
        }
    </script>

    <body>
        <input id="login" type="button" value="login" onclick="callDeviceScan('login', '1');" />
        <input id="buy" type="button" value="buy" onclick="callDeviceScan('buy', '2');" />
    </body> 
</html>
```

No exemplo acima, foi criada uma função de suporte **callDeviceScan** para poder atribuir o uso do Device Scan ao clique de um botão e a função de coleta de dados pode ser chamada duas vezes:

* A primeira quando o usuário pressionar o botão de login, e as características e comportamentos do usuário até este evento serão enviadas para os servidores da QI Tech com os identificadores web_token, session_id, event_type ("login") e event_id ("1").

* A segunda quando o usuário pressionar o botão de compra, coletando os comportamentos do usuário utilizando os mesmos identificadores web_token (referente a sua empresa) e session_id (referente a sessão do seu usuário) mas um event_type ("buy") e event_id("2") distintos, indicando que um evento diferente do anterior foi realizado neste passo, mapeando assim toda a jornada do usuário pelo seu website.

---

# Implementação

URL: /documentation/caas/device_scan/web/example

```html
   <html>
    <head>
        <script src="https://ds.viewpkg.com/device-scan-2-1-1.js"></script>
    </head>

    <script>
        var deviceScan = new vPkg.DeviceScan('web_token', 'session_id')
        deviceScan.setSandbox()
        deviceScan.setGeoLocation(true)
        deviceScan.info('event_type', 'event_id')
            .then((res) => console.log(res))
            .catch((error) => console.log(error))
    </script>
   </html>
```

A biblioteca realiza uma análise do usuário através de uma chamada da função **.info()**, que pertence a classe **DeviceScan**, que está contida em nossa biblioteca **vPkg**, conforme o exemplo acima. As variávies 'web_token', 'session_id', 'event_type' (**opcional**) e 'event_id' (**opcional**) devem ser substituídas pelos **seus respectivos valores reais**. Em caso de sucesso a biblioteca irá retornar uma String indicando o sucesso da coleta, e em caso de falha irá retornar uma String indicando o tipo do erro.

---

# Importando a biblioteca

URL: /documentation/caas/device_scan/web/import

Para importar a nossa biblioteca, adicione a URL em uma TAG **src** no HTML de seu website:

```html
    <script src = "https://ds.viewpkg.com/device-scan-2-1-1.js"></script>
```

---

# Coletando os Retornos

URL: /documentation/caas/device_scan/web/information_gathering

A Web Device Scan SDK devolve uma _Promise_, que irá retornar uma **String** indicando a finalização do fluxo para os casos de sucesso. 
Já em casos de erro, irá retornar uma **String** com a descrição do erro. Abaixo está um exemplo de como mapear cada um desses casos e pegar seus resultados:

```html
    <script>
        var deviceScan = new vPkg.DeviceScan('web_token', 'session_id')
        deviceScan.setSandbox()
        deviceScan.setGeoLocation(true)
        deviceScan.info('event_type', 'event_id')
            .then((res) => console.log(res))
            .catch((error) => console.log(error))
    </script>
```

### Retorno de Sucesso

Retorno | Descrição
--------- | ---------
Device Scan Successfully Sent | O escaneamento do dispositivo foi realizado com sucesso, assim como o envio das informações extraídas.

### Retorno de Erro

Erro | Descrição
--------- | ---------
Web Token Error | Web Token utilizado é inválido. Caso tenha certeza que esteja utilizando corretamente o Web Token que foi provido pela QI Tech, entre em contato com nosso suporte (suporte.caas@qitech.com.br) imediatamente.
Invalid Request | Informações do dispositivo não foram coletadas da maneira correta.
Internal Server Error | Ocorreu um erro inesperado, checar conexão com internet.

---

# Introdução

URL: /documentation/caas/device_scan/web/introduction

Bem vindo ao manual de integração do Web Device Scan da QI Tech! Você pode utilizar a nossa biblioteca para coletar informações do dispositivo, do navegador e do comportamento do usuário em seu website e assim melhorar a assertividade das decisões.

Neste passo a passo você encontrará detalhes da biblioteca bem como um exemplo de implementação em javascript. Com isso você possui as ferramentas 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. A seleção é realizada por meio de enumerador repassado no construtor do SDK, no momento, os seguintes ambientes estão disponíveis:

* Produção - `production`
* Sandbox - `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.  
:::