Guias de Desenvolvimento

Signing Sessions

Guias dos SDKs

Página Hospedada de Liveness — Guia de Testes Manuais E2E

Guia de testes ponta a ponta para a página React de liveness hospedada em id-hml.signdocs.com.br (hml) / id.signdocs.com.br (prod).

Pré-requisitos

Passo a passo: Fluxo Principal (Happy Path)

1. Obter token de acesso

TOKEN=$(curl -s -X POST "$API_URL/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials&client_id=$CLIENT_ID&client_secret=$CLIENT_SECRET&scope=transactions:read transactions:write steps:write" \
  | jq -r '.access_token')

2. Criar uma transação BIOMETRIC

TX=$(curl -s -X POST "$API_URL/v1/transactions" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: test-$(date +%s)" \
  -d '{
    "purpose": "DOCUMENT_SIGNATURE",
    "policy": { "profile": "BIOMETRIC" },
    "signer": { "name": "Manual Test", "userExternalId": "manual_test_1", "cpf": "12345678901" }
  }')

TX_ID=$(echo $TX | jq -r '.transactionId')
STEP_ID=$(echo $TX | jq -r '.steps[0].stepId')
echo "Transaction: $TX_ID, Liveness Step: $STEP_ID"

3. Iniciar liveness com modo de captura HOSTED_PAGE

START=$(curl -s -X POST "$API_URL/v1/transactions/$TX_ID/steps/$STEP_ID/start" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"captureMode": "HOSTED_PAGE"}')

HOSTED_URL=$(echo $START | jq -r '.hostedUrl')
SESSION_ID=$(echo $START | jq -r '.livenessSessionId')
echo "Open in browser: $HOSTED_URL"

4. Abrir a URL hospedada no navegador

5. Completar a etapa de liveness via API

curl -s -X POST "$API_URL/v1/transactions/$TX_ID/steps/$STEP_ID/complete" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"livenessSessionId\": \"$SESSION_ID\"}" | jq .

Esperado: "status": "COMPLETED", "confidence" acima do limiar.

6. Continuar pela etapa de match e finalizar

# Obter o ID da etapa de match
MATCH_STEP_ID=$(echo $TX | jq -r '.steps[1].stepId')

# Iniciar match
curl -s -X POST "$API_URL/v1/transactions/$TX_ID/steps/$MATCH_STEP_ID/start" \
  -H "Authorization: Bearer $TOKEN" | jq .

# Completar match (o frame de liveness é carregado no servidor a partir do S3)
# O usuário deve ter sido cadastrado previamente (veja etapa 2: userExternalId)
curl -s -X POST "$API_URL/v1/transactions/$TX_ID/steps/$MATCH_STEP_ID/complete" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}' | jq .

# Upload do documento
curl -s -X POST "$API_URL/v1/transactions/$TX_ID/document" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": "'$(echo -n '%PDF-1.4 test' | base64)'"}' | jq .

# Finalizar
curl -s -X POST "$API_URL/v1/transactions/$TX_ID/finalize" \
  -H "Authorization: Bearer $TOKEN" | jq .

Variante: Imagem de Referência por Transação

Em vez de depender de um usuário previamente cadastrado, o banco pode fornecer uma imagem de referência diretamente na requisição de conclusão do match. Isso requer featureFlags.perTransactionReferenceEnabled: true na configuração do tenant no DynamoDB.

1. Criar transação (sem necessidade de cadastro prévio)

TX=$(curl -s -X POST "$API_URL/v1/transactions" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Idempotency-Key: test-ref-$(date +%s)" \
  -d '{
    "purpose": "DOCUMENT_SIGNATURE",
    "policy": { "profile": "BIOMETRIC" },
    "signer": { "name": "Per-Tx Ref Test", "userExternalId": "per_tx_ref_test_1", "cpf": "12345678901" }
  }')

TX_ID=$(echo $TX | jq -r '.transactionId')
LIVENESS_STEP_ID=$(echo $TX | jq -r '.steps[0].stepId')
MATCH_STEP_ID=$(echo $TX | jq -r '.steps[1].stepId')

2. Completar liveness (mesmo procedimento das etapas 3-5 do fluxo principal)

Inicie com HOSTED_PAGE, abra no navegador, capture o rosto e depois complete via API.

3. Completar match com imagem de referência por transação

# Codifique uma foto conhecida do usuário em base64
REF_IMAGE=$(base64 -w0 /path/to/known-photo.jpg)

# Iniciar match
curl -s -X POST "$API_URL/v1/transactions/$TX_ID/steps/$MATCH_STEP_ID/start" \
  -H "Authorization: Bearer $TOKEN" | jq .

# Completar match com referência por transação (frame de liveness carregado no servidor)
curl -s -X POST "$API_URL/v1/transactions/$TX_ID/steps/$MATCH_STEP_ID/complete" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d "{\"referenceImage\": {\"source\": \"BASE64_IMAGE\", \"data\": \"$REF_IMAGE\"}}" | jq .

Esperado: "status": "COMPLETED", "similarity" acima do limiar, "enrollmentRef.source": "TRANSACTION_PROVIDED".

Alternativa: DOCUMENT_PHOTO_MATCH

Como alternativa ou complemento ao liveness puro, o tipo de etapa DOCUMENT_PHOTO_MATCH permite comparar a face do usuário com uma foto extraída de um documento (CNH, RG ou passaporte). Esse fluxo é útil como fallback quando o liveness apresenta dificuldades.

Fluxo de Document Photo Match

  1. Crie a transação com um perfil que inclua DOCUMENT_PHOTO_MATCH (via CUSTOM)
  2. Inicie a etapa DOCUMENT_PHOTO_MATCH via POST .../steps/{stepId}/start
  3. Envie a foto do documento no complete:
    curl -s -X POST "$API_URL/v1/transactions/$TX_ID/steps/$DOC_STEP_ID/complete" \
      -H "Authorization: Bearer $TOKEN" \
      -H "Content-Type: application/json" \
      -d '{
        "documentImage": "'$(base64 -w0 /path/to/cnh-frente.jpg)'",
        "documentType": "CNH"
      }' | jq .
  4. O servidor extrai a face do documento, compara com a referência biométrica e retorna o similarity score
Nota: Quando o tenant possui biometricRequired habilitado, o campo geolocation é obrigatório também para DOCUMENT_PHOTO_MATCH.

Observações Importantes

Matriz de Testes

Cenário Como Testar Resultado Esperado
Fluxo principal (cadastro) Modo PRODUCTION, câmera real, usuário previamente cadastrado Liveness aprovado, match carrega o frame no servidor, compara com a imagem de cadastro
Fluxo principal (ref. por transação) Modo PRODUCTION, câmera real, referenceImage no corpo da requisição Liveness aprovado, match carrega o frame no servidor, compara com a imagem fornecida, enrollmentRef.source: "TRANSACTION_PROVIDED"
Token expirado Aguarde 10+ minutos após gerar a hostedUrl e então abra-a 403 do Lambda@Edge
Token reutilizado Abra a hostedUrl 3+ vezes 1o e 2o carregamento funcionam, 3o carregamento retorna 403
Parâmetros ausentes Abra https://id-hml.signdocs.com.br sem ?token= Estado de erro do React: "Link de verificacao invalido ou expirado"
Kill switch (hosted_liveness) Defina killSwitch.hosted_liveness: true na configuração do tenant (DynamoDB) Início da etapa retorna 422 Unprocessable Entity
Kill switch (biometric) Defina killSwitch.biometric: true na configuração do tenant (DynamoDB) Início da etapa retorna 422 Unprocessable Entity
Sessão inválida Altere o parâmetro ?session= na URL FaceLivenessDetector exibe erro
Navegador mobile Abra a hostedUrl no Safari do iOS / Chrome do Android Interface de câmera funciona, captura facial bem-sucedida
Sem câmera Abra em navegador sem câmera FaceLivenessDetector exibe erro "camera not found"

Domínios

Ambiente Domínio de Liveness Hospedado Domínio da API
hml id-hml.signdocs.com.br api-hml.signdocs.com.br
prod id.signdocs.com.br api.signdocs.com.br

Verificação de DNS

# Verificar se o DNS resolve para o CloudFront
dig id-hml.signdocs.com.br

# Verificar se o HTTPS funciona
curl -I https://id-hml.signdocs.com.br