Guia Detalhado de Uso

Plugin Flutter oficial da CertiFace para integrar jornadas de liveness (detecção de vida) nos apps, com os provedores iProov e FaceTec. O pacote expõe permissões de câmera, início do fluxo nativo em tela cheia e customização visual opcional via ThemeBuilder.

Sumário

  1. Visão Geral
  2. Requisitos de Compatibilidade
  3. Instalação
  4. Configuração
  5. Provedor de Liveness
    5.1. Provedor IProov
    5.2. Provedor Facetec
  6. Estrutura das Classes Importantes
  7. Principais Classes e Métodos de Chamada
  8. Fluxo de Telas
    8.1. Telas CertiFace
    8.2. Telas IProov
    8.3. Telas Facetec
  9. Ambiente de Testes
  10. Boas Práticas
  11. Changelogs e Versões
  12. Links Externos
  13. FAQ e objeções frequentes
  14. Licença e suporte

1. Visão Geral

O Certiface SDK Flutter permite integrar fluxos de verificação facial com liveness em aplicações Flutter, delegando a captura e a lógica biométrica ao SDK nativo (Android e iOS).

O SDK oferece:

  • Verificação de pré-requisitos
    Consulta e solicitação de permissão de câmera (checkPermission / askPermission).

  • Execução da jornada
    startLiveness abre o fluxo nativo em tela cheia com a appKey e o ambiente (HML ou PRD).

  • Escolha do motor de liveness
    Parâmetro provider com valores 'IPROOV' ou 'FACETEC'.

  • Interface integrada ao app
    Telas hospedadas pelo SDK nativo (não é um preview de câmera embutido em um Widget arbitrário).

  • Retorno de resultados
    Future<Map<String, dynamic>> contendo:

    • status
    • result
    • message

    Falhas no canal Flutter ↔ nativo são retornadas como PlatformException.

Fora do escopo do plugin:

  • Emissão ou gestão de App Key
    Segue o fluxo acordado com a CertiFace.
  • Configuração nativa (Maven, CocoaPods, credenciais)
    Utilize os guias oficiais disponíveis em Links externos.

2. Requisitos de Compatibilidade

Antes de integrar, confira:

RequisitoDetalhe
Flutter/ DartFlutter >=3.3.0, Dart SDK ^3.5.3 (conforme o pacote publicado).
Projeto hostProjeto Flutter com suporte a plugins nativos (Android e/ou iOS).
AndroidGradle 8.0+; minSdkVersion 26 (Android 8.0) ou superior; permissão de câmera; acesso à internet; Activity válida quando startLiveness for chamado.
iOS13.0+; NSCameraUsageDescription; internet.
Câmera e redeO fluxo de liveness depende de câmera frontal (configurável no tema, apenas para o provedor iProov) e conectividade para os serviços Certiface.

iOS: Janela e rootViewController: a implementação atual obtém o rootViewController a partir da janela principal da aplicação. Em cenários com múltiplas janelas, deep links ou estados incomuns de ciclo de vida, valide o fluxo em dispositivo real. Erros típicos incluem código NO_CONTROLLER quando o controlador não está disponível.

Android: Activity: se não houver Activity anexada ao plugin (por exemplo, contexto errado), o canal pode retornar NO_ACTIVITY.


3. Instalação

Via pub.dev

dependencies:
  certiface_sdk: ^1.2.0

Via GitHub

dependencies:
  certiface_sdk:
    git:
      url: https://github.com/oititec/certiface-sdk-flutter.git
      ref: main # ou a branch / tag desejada

Depois execute flutter pub get.


4. Configuração

  1. Adicione a dependência certiface_sdk no pubspec.yaml do seu app.
  2. Conclua a configuração nativa (repositórios Maven, CocoaPods, permissões e chaves) seguindo o Guia de Instalação Flutter.
  3. Obtenha a App Key (e demais credenciais) pelo fluxo acordado com a Certiface (painel, API de credenciais ou integração do seu produto).
  4. Importe o SDK:
import 'package:certiface_sdk/certiface_sdk.dart';
import 'package:certiface_sdk/common/theme_builder.dart'; // apenas se usar tema customizado
  1. Mantenha uma instância de CertifaceSdk (por exemplo no State de um widget ou em um serviço injetável):
final _certifaceSdk = CertifaceSdk();

Canal de comunicação: o plugin usa o method channel oiti_sdk entre Dart e o código nativo.


Provedor de Liveness

Não é necessário instanciar um provedor em Dart.
Basta informar o parâmetro provider na chamada de startLiveness.

Provedores disponíveis

ProvedorValor (provider)Observação
iProov'IPROOV'Jornada com verificação passiva (inclui uso de iluminação/desafio luminoso conforme o SDK iProov).
FaceTec'FACETEC'Jornada com verificação ativa (orientação de movimentos / rosto), conforme o SDK FaceTec.
Outro valorComportamento diferente por plataforma — veja o alerta abaixo.

⚠️ Validação de provider difere entre Android e iOS:

  • Android: a comparação é case-insensitive. Qualquer valor diferente de 'IPROOV'/'FACETEC' (em qualquer caixa) faz o canal retornar erro INVALID_ARGUMENT com a mensagem provider inválido.
  • iOS: a comparação é case-sensitive e só reconhece a string exata 'FACETEC' para selecionar o FaceTec. Qualquer outro valor — incluindo erros de digitação, caixa diferente ('facetec') ou mesmo 'IPROOV'não gera erro: o fluxo iProov é iniciado silenciosamente.

Recomenda-se sempre usar as strings exatas 'IPROOV' ou 'FACETEC' (maiúsculas) para evitar esse comportamento divergente.

💡 Dica:

Na API Dart, provider e environment são strings (não há enum público LivenessProvider no pacote). Para legibilidade no app, é possível definir constantes:

const kProviderIproov = 'IPROOV';
const kProviderFacetec = 'FACETEC';

Fluxo recomendado antes de startLiveness:

  1. Verificar permissão de câmera
    Use checkPermission().

  2. Solicitar permissão (se necessário)
    Use askPermission() (abre diálogo nativo).

  3. Iniciar o fluxo de liveness com uma App Key válida
    Chame startLiveness informando:

    • environment
    • provider
    • (opcional) tema customizado
  4. Tratar o resultado
    O retorno é Map<String, dynamic> contendo:

    • status
    • result
    • message

    Falhas no canal Flutter ↔ nativo retornam como PlatformException.

Boas práticas:

Em widgets, após await, verifique se o widget ainda está montado (por exemplo mounted em StatefulWidget) antes de chamar setState.

Personalização visual:

  • isCustomEnabled: false use o tema padrão do SDK; theme deve ser null.
  • isCustomEnabled: true construa o tema com ThemeBuilder e passe theme: builder.toJson().

5.1. Provedor: iProov

  • Definição do provider
    Passe provider: 'IPROOV'
    (case-insensitive no Android; no iOS, qualquer valor diferente de 'FACETEC' já resulta em iProov — veja o alerta na seção anterior)

  • Customização do iProov (miolo)
    Pode ser ajustada de duas formas:

    • Via ThemeBuilder global (setFontResource, setFilter, setOrientation, setCamera, setOvalColors, etc. — esses campos só se aplicam ao iProov)
    • Via setIproovTheme(...) dentro do ThemeBuilder
  • Demais telas do fluxo (casca Certiface)
    As telas de:

    • instruções
    • permissão
    • processamento

    usam os mesmos blocos de tema (instructions, permission, processing) compartilhados com a casca do FaceTec. Já a tela de resultado (setResultTheme) é exclusiva do iProov — não é aplicada quando provider: 'FACETEC'.

Exemplo mínimo:

final res = await certifaceSdk.startLiveness(
  appKey,
  environment: 'HML',
  provider: 'IPROOV',
  isCustomEnabled: false,
  theme: null,
);

5.2. Provedor: FaceTec

  • Definição do provider
    Passe provider: 'FACETEC' — no iOS, a string deve ser exatamente 'FACETEC' (case-sensitive); qualquer outro valor é tratado como iProov (veja o alerta na seção anterior).

  • Renderização da experiência
    A experiência do FaceTec é totalmente renderizada pelo SDK nativo.

  • Customização visual (limitada em relação ao iProov)
    O ThemeBuilder só alimenta a (casca Certiface) para o FaceTec em:

    • telas de instruções
    • permissão
    • processamento

    ⚠️ A tela de resultado (setResultTheme) e os campos "globais" do ThemeBuilder (setFontResource, setIsEnabledScreenShots, setDisableExteriorEffects, setTimeoutSecs, setPromptRoundedCorners, setFilter, setOrientation, setCamera, setOvalColors) não têm efeito no provedor FaceTec — tanto no Android quanto no iOS, esses campos só são lidos pelo caminho de customização do iProov. As telas específicas do FaceTec (oval, guidance, retry, resultado) usam customização própria do SDK nativo FaceTec, que não é exposta pela API pública ThemeBuilder deste plugin no momento.

Exemplo mínimo:

final res = await certifaceSdk.startLiveness(
  appKey,
  environment: 'HML',
  provider: 'FACETEC',
  isCustomEnabled: false,
  theme: null,
);

Chamada típica com tema customizado:

final res = await certifaceSdk.startLiveness(
  appKey,
  environment: 'HML',
  provider: 'FACETEC',
  isCustomEnabled: useCustomTheme,
  theme: useCustomTheme ? myThemeBuilder.toJson() : null,
);

6. Estrutura das classes importantes

Visão geral (API pública e canal)

flowchart LR
  subgraph dart [Dart]
    CertifaceSdk
    ThemeBuilder
  end
  subgraph bridge [Plugin]
    CertifaceSdkPlatform
    MethodChannelCertifaceSdk
  end
  CertifaceSdk --> CertifaceSdkPlatform
  CertifaceSdkPlatform --> MethodChannelCertifaceSdk
  ThemeBuilder -->|toJson no startLiveness| MethodChannelCertifaceSdk

Estrutura do ThemeBuilder:

ComponenteDescrição
ThemeBuilderOpções globais (título, cores, oval, timeout, filtro, orientação, câmera, etc.)
InstructionsThemeBuilderConfigurado via setInstructionsTheme
PermissionThemeBuilderConfigurado via setPermissionTheme
ProcessingThemeBuilderConfigurado via setProcessingTheme
ResultThemeBuilderConfigurado via setResultTheme
IproovThemeBuilderConfigurado via setIproovTheme

Arquivos de referência no repositório:


7. Principais Classes e Métodos de Chamada

Classe CertifaceSdk

MétodoDescrição
Future<String?> getPlatformVersion()Informação opcional da versão nativa; útil para diagnóstico.
Future<bool> checkPermission()Indica se o app já tem permissão de câmera; não exibe UI.
Future<bool> askPermission()Solicita permissão de câmera ao usuário (fluxo nativo).
Future<Map<String, dynamic>> startLiveness(...)Inicia a jornada de liveness em tela cheia nativa.

Assinatura de startLiveness:

Future<Map<String, dynamic>> startLiveness(
  String appKey, {
  String environment = 'HML',
  String provider = 'IPROOV',
  bool isCustomEnabled = false,
  Map<String, dynamic>? theme,
});
ParâmetroTipoDescrição
appKeyStringObrigatório. Chave da aplicação fornecida pela Certiface.
environmentString'HML' (homologação) ou 'PRD' (produção). Outro valor é tratado como HML no iOS; no Android, valores diferentes de PRD tendem a homologação.
providerString'IPROOV' ou 'FACETEC'.
isCustomEnabledboolSe true, o mapa theme é aplicado na UI nativa; se false, tema padrão (theme pode ser null).
themeMap<String, dynamic>?Normalmente o retorno de ThemeBuilder() encadeado com .toJson() quando isCustomEnabled é true.

Tratamento do retorno

O plugin devolve um mapa com a leitura usual:

  • Se res['status'] == 'success': sucesso; Detalhes costumam vir em res['result'] (mapa com campos conforme contrato do backend / SDK nativo).
  • Caso contrário: erro de negócio ou de fluxo, com mensagem em res['message'].

Exemplo:

import 'package:flutter/services.dart';
import 'package:certiface_sdk/certiface_sdk.dart';

Future<void> runLiveness(CertifaceSdk sdk, String appKey) async {
  Map<String, dynamic> res = {};
  try {
    res = await sdk.startLiveness(
      appKey,
      environment: 'HML',
      provider: 'FACETEC',
      isCustomEnabled: false,
      theme: null,
    );
  } on PlatformException catch (e) {
    // Falha no method channel (argumento inválido, activity indisponível, etc.)
    // e.code, e.message
    return;
  }

  if (res['status'] == 'success') {
    final inner = res['result'];
    // use inner conforme o guia de retornos da Certiface
  } else {
    final message = res['message'];
    // exibir erro ao usuário
  }
}

Para o significado exato de cada campo em result, consulte o Guia de Tratamento de Retorno.

ThemeBuilder e exemplos com propriedades

API fluente
Cada método set... retorna o próprio builder, permitindo encadeamento:

ThemeBuilder()
  .setTitle(...)
  .setInstructionsTheme(...)
  .toJson();
  • Envio para o nativo

    O objeto enviado ao SDK nativo é sempre o resultado de toJson() ao final do encadeamento.

Formatos e padrões

  • Cores Hex string: #RRGGBB
  • Oval: Formato inteiro: 0xAARRGGBB

Configurações adicionais

Os valores de: setFilter, setOrientation, setCamera e nomes de fontes/assets devem seguir o guia de customização Flutter e os recursos nativos do app.

Tema global (ThemeBuilder)

⚠️ Estas propriedades globais só têm efeito quando provider: 'IPROOV'. No FaceTec elas são ignoradas pelo código nativo (Android e iOS) — veja a seção 5.2 Provedor: FaceTec.

PropriedadeTipoUso
setTitleStringTítulo da jornada
setTitleColorString (hex)Cor do título ('#RRGGBB')
setHeaderBackgroundColorString (hex)Fundo do cabeçalho
setPromptTextColor
setPromptBackgroundColor
String (hex)Texto e fundo do prompt
setSurroundColorString (hex)Cor ao redor da área de captura
setFontResourceintFonte nativa
setIsEnabledScreenShotsboolPermite capturas de tela
setDisableExteriorEffectsboolDesativa efeitos exteriores
setTimeoutSecsintTimeout da sessão (segundos)
setPromptRoundedCornersboolCantos arredondados do prompt
setFilter(type, style)StringEx: 'Natural', 'CLEAR'
setOrientation(gpa, la)StringEx: 'PORTRAIT'
setCameraStringEx: 'FRONT'
setOvalColors(...)int (ARGB)Cores do oval (0xAARRGGBB)
💡

Importante:

Cores usam: '#RRGGBB' / Oval usa: 0xAARRGGBB

Instruções (setInstructionsThemeInstructionsThemeBuilder)

ÁreaSetters (exemplos)
CoressetStatusBarColor,
setBackgroundColor,
setBackButtonIconColor,
setBackButtonBackgroundColor,
setBackButtonBorderColor,
setBottomSheetColor,
setTitleColor,
setCaptionColor,
setFirstInstructionTitleColor,
setSecondInstructionTitleColor,
setContinueButtonTextColor,
setContinueButtonBackgroundColor,
setContinueButtonBorderColor,
setContinueButtonColor,
setBottomSheetCornerRadius
TextossetTitleText,
setCaptionText,
setFirstInstructionText,
setSecondInstructionText,
setContinueButtonText,
setDocumentTipsInstructionText,
setDocumentTypesInstructionText
FontessetTitleFont,
setCaptionFont,
setFirstInstructionTitleFont,
setSecondInstructionTitleFont,
setContinueButtonFont
AssetssetBackButtonIconAsset,
setContextImageAsset,
setFirstInstructionIconAsset,
setSecondInstructionIconAsset
(nomes de recurso nativos)
ConfiguraçãosetShowInstructionScreen,
setStatusBarIsDarkIcons

Permissão (setPermissionThemePermissionThemeBuilder)

ÁreaSetters (exemplos)
CoressetStatusBarColor,
setBackgroundColor,
setTitleColor,
setCaptionColor,
setCheckPermissionButtonTextColor,
setCheckPermissionButtonBackgroundColor,
setCheckPermissionButtonBorderColor,
setCheckPermissionButtonStyle,
setBackButtonIconColor,
setCameraImageColor
TextossetTitle,
setCaptionText,
setCheckPermissionButtonText
FontessetTitleFont,
setCaptionFont,
setCheckPermissionButtonFont
AssetssetBackButtonIconAsset,
setCameraImageAsset
OutrossetStatusBarIsDarkIcons

Processamento (setProcessingThemeProcessingThemeBuilder)

SetterDescrição
setStatusBarColorCor da status bar.
setBackgroundColorFundo da tela de processamento.
setLoadingColor
setLoadingDialogColor
Cor do indicador/diálogo de loading.
setLoadingIndicatorSizeTamanho do indicador (int).
setLoadingIndicatorWidthEspessura do indicador (int).
setStatusBarIsDarkIconsÍcones escuros na status bar.

Resultado (setResultThemeResultThemeBuilder)

ÁreaSetters (exemplos)
SucessosetSuccessBackgroundColor,
setSuccessTextColor,
setSuccessText,
setSuccessIcon,
setSuccessStatusBarColor,
setStatusBarSuccessColor,
setStatusBarSuccessIsDarkIcons
ErrosetErrorBackgroundColor,
setErrorTextColor,
setErrorText,
setErrorIcon,
setErrorStatusBarColor,
setStatusBarErrorColor,
setStatusBarErrorIsDarkIcons
RetrysetRetryButtonColor,
setRetryButtonTextColor,
setRetryButtonText,
setRetryIcon,
setRetryButtonFont
GeralsetTextFont

iProov (setIproovThemeIproovThemeBuilder)

Ajustes específicos do fluxo iProov (além dos campos globais do ThemeBuilder que também entram no payload iproov via toJson()).

ÁreaSetters
CoressetTitleColor,
setHeaderBackgroundColor,
setPromptTextColor,
setPromptBackgroundColor,
setSurroundColor
TextossetTitleText
FontessetInstructionsTitleFont,
setInstructionsCaptionFont,
setResultMessageFont,
setResultRetryButtonFont
AssetssetCloseButtonIconAsset,
setLogoImageAsset

Exemplo mínimo

import 'package:certiface_sdk/common/theme_builder.dart';

ThemeBuilder buildThemeMinimal({required bool showInstructionScreen}) {
  return ThemeBuilder()
      .setTitle('Verificação facial')
      .setHeaderBackgroundColor('#1A1A1A')
      .setOvalColors(
        ready: 0xFF00FF88,
        notReady: 0xFFFF4444,
        stroke: 0xFFFFFFFF,
        completed: 0xFF00FF88,
      )
      .setInstructionsTheme((b) => b
          .setTitleText('Instruções')
          .setShowInstructionScreen(showInstructionScreen)
          .setContinueButtonText('Iniciar'))
      .setPermissionTheme((b) => b.setTitle('Permissões necessárias'));
}

await certifaceSdk.startLiveness(
  appKey,
  isCustomEnabled: true,
  theme: buildThemeMinimal(showInstructionScreen: true).toJson(),
);

Exemplo estendido (todas as áreas + iProov)

Use como referência e remova o que não precisar. Substitua os nomes de fonte ('sixty') e de assets ('shell', 'back_icon', etc.) pelos recursos que existem no seu Android / iOS.

import 'package:certiface_sdk/common/theme_builder.dart';

ThemeBuilder buildFullTheme({required bool showInstructionScreen}) {
  return ThemeBuilder()
      // --- Global ---
      .setTitle('Verificação facial')
      .setTitleColor('#FFFFFF')
      .setHeaderBackgroundColor('#1A1A1A')
      .setPromptTextColor('#FFFFFF')
      .setPromptBackgroundColor('#2A2A2A')
      .setSurroundColor('#00FF88')
      .setFontResource(0)
      .setIsEnabledScreenShots(true)
      .setDisableExteriorEffects(true)
      .setTimeoutSecs(90)
      .setPromptRoundedCorners(true)
      .setFilter('Natural', 'CLEAR')
      .setOrientation(gpa: 'PORTRAIT', la: 'PORTRAIT')
      .setCamera('FRONT')
      .setOvalColors(
        ready: 0xFF00FF88,
        notReady: 0xFFFF4444,
        stroke: 0xFFFFFFFF,
        completed: 0xFF00FF88,
      )
      // --- Instruções ---
      .setInstructionsTheme((b) => b
          .setTitleText('Instruções')
          .setTitleColor('#FFFFFF')
          .setCaptionText('Siga as instruções na tela.')
          .setCaptionColor('#CCCCCC')
          .setBackgroundColor('#2A2A2A')
          .setBottomSheetColor('#3A3A3A')
          .setDocumentTipsInstructionText('Dicas de documento')
          .setDocumentTypesInstructionText('Tipos aceitos')
          .setBottomSheetCornerRadius(20.0)
          .setContinueButtonText('Iniciar verificação')
          .setContinueButtonColor('#00FF88')
          .setContinueButtonTextColor('#000000')
          .setShowInstructionScreen(showInstructionScreen)
          .setStatusBarColor('#1A1A1A')
          .setStatusBarIsDarkIcons(false)
          .setTitleFont('sixty')
          .setCaptionFont('sixty')
          .setFirstInstructionTitleFont('sixty')
          .setSecondInstructionTitleFont('sixty')
          .setContinueButtonFont('sixty')
          .setBackButtonIconAsset('shell')
          .setContextImageAsset('shell')
          .setFirstInstructionIconAsset('shell')
          .setSecondInstructionIconAsset('shell'))
      // --- Permissão ---
      .setPermissionTheme((b) => b
          .setTitle('Permissões necessárias')
          .setTitleColor('#FFFFFF')
          .setBackgroundColor('#2A2A2A')
          .setCheckPermissionButtonText('Permitir câmera')
          .setCheckPermissionButtonStyle('#00FF88')
          .setStatusBarColor('#2A2A2A')
          .setStatusBarIsDarkIcons(false)
          .setTitleFont('sixty')
          .setCaptionFont('sixty')
          .setCheckPermissionButtonFont('sixty')
          .setBackButtonIconAsset('back_icon')
          .setCameraImageAsset('camera_icon'))
      // --- Processamento ---
      .setProcessingTheme((b) => b
          .setBackgroundColor('#000000')
          .setLoadingDialogColor('#FFFFFF')
          .setLoadingIndicatorSize(120)
          .setLoadingIndicatorWidth(12)
          .setStatusBarColor('#000000')
          .setStatusBarIsDarkIcons(true))
      // --- Resultado ---
      .setResultTheme((b) => b
          .setSuccessBackgroundColor('#E8F5E8')
          .setSuccessIcon('success_icon')
          .setSuccessText('Verificação concluída.')
          .setSuccessTextColor('#2E7D32')
          .setErrorBackgroundColor('#FFEBEE')
          .setErrorIcon('error_icon')
          .setErrorText('Falha na verificação. Tente novamente.')
          .setErrorTextColor('#C62828')
          .setRetryButtonColor('#00FF88')
          .setRetryButtonText('Tentar novamente')
          .setRetryButtonTextColor('#000000')
          .setStatusBarSuccessColor('#E8F5E8')
          .setStatusBarErrorColor('#FFEBEE')
          .setStatusBarSuccessIsDarkIcons(true)
          .setStatusBarErrorIsDarkIcons(true)
          .setTextFont('sixty')
          .setRetryButtonFont('sixty'))
      // --- Específico iProov ---
      .setIproovTheme((b) => b
          .setTitleText('Verificação facial')
          .setTitleColor('#FFFFFF')
          .setHeaderBackgroundColor('#1A1A1A')
          .setPromptTextColor('#FFFFFF')
          .setPromptBackgroundColor('#2A2A2A')
          .setSurroundColor('#00FF88')
          .setInstructionsTitleFont('sixty')
          .setInstructionsCaptionFont('sixty')
          .setResultMessageFont('sixty')
          .setResultRetryButtonFont('sixty')
          .setLogoImageAsset('logo')
          .setCloseButtonIconAsset('close_icon'));
}

// Uso com FaceTec ou iProov:
await certifaceSdk.startLiveness(
  appKey,
  environment: 'HML',
  provider: 'FACETEC', // ou 'IPROOV'
  isCustomEnabled: true,
  theme: buildFullTheme(showInstructionScreen: true).toJson(),
);

Assets referenciados nos setters (ícones, logos, imagens de contexto) precisam existir no projeto Android / iOS com os mesmos nomes de recurso configurados no DevCenter, conforme o guia de customização.


8. Fluxo de telas

A ordem exata e os nomes internos das telas podem variar com a versão do SDK nativo Certiface/iProov/FaceTec. Use esta visão como modelo mental e valide com os guias oficiais e com testes em dispositivo.

8.1. Telas Certiface (camada Oiti)

Camadas de experiência comuns à jornada, configuráveis pelo ThemeBuilder quando isCustomEnabled é true:

EtapaBuilder / temaConteúdo típico
InstruçõessetInstructionsThemeTextos, cores, fontes, assets; setShowInstructionScreen para exibir ou pular a tela de instruções. Aplica-se a iProov e FaceTec.
PermissãosetPermissionThemeOrientação ao usuário antes de conceder câmera. Aplica-se a iProov e FaceTec.
ProcessamentosetProcessingThemeIndicadores de carregamento/aguardando processamento. Aplica-se a iProov e FaceTec.
ResultadosetResultThemeTelas de sucesso, erro e opção de nova tentativa. ⚠️ Aplica-se apenas ao iProov — no FaceTec, a tela de resultado usa o comportamento padrão do SDK nativo e não é customizável por este builder.

8.2. Telas iProov

Após a casca Certiface (quando presente), o usuário entra no fluxo nativo iProov (captura e validação conforme o provedor). Customizações específicas costumam passar por setIproovTheme. Detalhes finos de UI e desafios estão no SDK iProov e na documentação Certiface.

8.3. Telas FaceTec

Após a casca Certiface (quando presente), o usuário percorre o fluxo nativo FaceTec (orientações de pose/movimento, feedback visual, etc.). Diferente do iProov, essas telas nativas do FaceTec (oval, guidance, retry, resultado) não são alimentadas pelo ThemeBuilder público deste plugin — apenas a casca Certiface (instruções, permissão, processamento) é customizável para o FaceTec. Consulte o DevCenter para limites e chaves específicas FaceTec.


9. Ambiente de Testes

Durante o desenvolvimento, utilize o ambiente HML com App Keys fornecidas pela equipe CertiFace.

⚠️ Evite o ambiente de produção (PRD) para testes manuais e massivos: use homologação até o go-live validado.

await sdk.startLiveness(appKey, environment: 'HML', provider: 'FACETEC');

10. Boas Práticas

TemaRecomendação
Ciclo de vidaApós await, verifique mounted antes de chamar setState.
SegurançaNão commite App Keys em repositórios públicos. Use variáveis de ambiente ou backend seguro.
ErrosTrate PlatformException (canal) e o retorno (status / message) para cobrir falhas nativas e de negócio.
AndroidGaranta que o app tenha uma Activity válida ao iniciar o liveness.
iOSTeste no fluxo real de abertura do app até a chamada do SDK.
AssetsCertifique-se de que os recursos do tema existem nos projetos nativos.
CoberturaTeste separadamente com iProov e FaceTec (pilhas nativas distintas).

Integração sugerida (serviço)

import 'package:flutter/services.dart';
import 'package:certiface_sdk/certiface_sdk.dart';

class LivenessService {
  LivenessService() : _sdk = CertifaceSdk();

  final CertifaceSdk _sdk;

  Future<bool> ensureCameraPermission() async {
    if (await _sdk.checkPermission()) return true;
    return _sdk.askPermission();
  }

  Future<Map<String, dynamic>> run({
    required String appKey,
    String environment = 'HML',
    String provider = 'FACETEC',
    bool customUi = false,
    Map<String, dynamic>? theme,
  }) async {
    if (appKey.trim().isEmpty) {
      throw StateError('App Key is required');
    }
    try {
      return await _sdk.startLiveness(
        appKey.trim(),
        environment: environment,
        provider: provider,
        isCustomEnabled: customUi,
        theme: customUi ? theme : null,
      );
    } on PlatformException catch (e) {
      rethrow; // ou mapear para seu modelo de erro
    }
  }
}

11.Changelogs e Versões

VersãoDataDescrição
1.0.025/03/2026Lançamento inicial para desenvolvedores (pub.dev).
1.1.008/04/2026Atualizado versão SDK iOS para 1.3.0
1.2.024/06/2026Atualização da FaceTec: 1.7.0(iOS) e 1.2.0(Android)
⚠️

Sempre consulte a documentação atualizada e a página do pacote no pub.dev para obter os detalhes mais recentes.


12. Links Externos


13. FAQ e objeções frequentes

  1. Existe enum LivenessProvider no Dart?

    Não na API pública atual. Use as strings 'IPROOV' e 'FACETEC' (ou constantes que você definir no app).

  2. Posso embutir a câmera de liveness dentro de um Container Flutter?

    Não. O fluxo é apresentado pelo SDK nativo em tela cheia; o Flutter apenas dispara e recebe o resultado.

  3. O que vem dentro de res['result']?

    Depende do contrato da versão do SDK / backend. Use o Guia de Tratamento de Retornos.

  4. Erro INVALID_ARGUMENT

    Em geral appKey ausente ou provider não suportado — mas essa validação de provider só existe no Android. No iOS, um provider inválido não gera erro: o fluxo assume iProov silenciosamente. Sempre use as strings exatas 'IPROOV' ou 'FACETEC'.

  5. Erro NO_ACTIVITY (Android)

    Nenhuma Activity disponível para o plugin no momento da chamada.

  6. Erro NO_CONTROLLER (iOS)

    Não foi possível obter o rootViewController da janela principal.

  7. Tema não aplicou/ícone quebrou

    Confira isCustomEnabled: true, theme não nulo e assets nativos com os nomes esperados. Lembre-se também que setResultTheme e os campos "globais" do ThemeBuilder (cores, oval, filtro, orientação, câmera, timeout etc.) só se aplicam ao provedor iProov — no FaceTec eles não têm efeito.

  8. O plugin substitui a configuração Maven/Pods?

    Não. A configuração do host continua obrigatória pelos guias de instalação.

  9. A customização visual funciona igual para iProov e FaceTec?

    Não. Para ambos, a casca Certiface (instruções, permissão, processamento) é customizável. Mas a tela de resultado e os campos globais do ThemeBuilder só afetam o iProov; as telas nativas específicas do FaceTec (oval, guidance, retry, resultado) não são expostas pela API Dart atual.


14. Licença e suporte

MIT License — veja o arquivo LICENSE.

Para suporte comercial e técnico, utilize os canais da CertiFace indicados no Portal de Atendimento.