BlendFi

Fluxo de KYC

Verifique a identidade do usuário com a Sumsub antes que ele transacione — geração de link, callbacks de status e o que cada resultado de KYC significa.

Compliance

Fluxo de KYC

Todo usuário final BlendFi precisa completar a verificação de identidade antes de movimentar dinheiro. Isso é uma exigência regulatória — sem um KYC approved, tentativas de criar uma cotação ou transação retornam 403 missing_capability para o usuário. A BlendFi cuida do KYC pela Sumsub; você não fala diretamente com a Sumsub.

Como tudo se encaixa

Seu app                 BlendFi                   Sumsub
   │                       │                         │
   ├─ POST /v1/users ─────►│                         │
   │◄──── usuário criado ──┤                         │
   │   (kyc: not_started)  │                         │
   │                       │                         │
   ├─ POST /v1/users/{id}/kyc ─►                     │
   │                       ├── cria applicant ──────►│
   │                       │◄──── id do applicant ───┤
   │                       ├── gera link websdk ────►│
   │                       │◄──── url assinada ──────┤
   │◄── submissão de kyc ──┤                         │
   │   (kyc: pending,      │                         │
   │    websdk_url)        │                         │
   │                       │                         │
   ├─ redireciona usuário final para websdk_url ─────►
   │                       │ (usuário envia docs)    │
   │                       │◄────── webhook ─────────┤
   │                       │  (resultado da revisão) │
   │◄── webhook pra você ──┤                         │
   │  (kyc: approved)      │                         │

Você só chama a BlendFi. A BlendFi chama a Sumsub por você e reflete os resultados de volta.

Cinco resultados

`not_started`

Usuário existe. A submissão de KYC ainda não foi iniciada. Não pode transacionar.

`pending`

Link WebSDK entregue. A Sumsub está revisando os documentos e a selfie. Não pode transacionar.

`approved`

Usuário passou no KYC. Pode transacionar. Validade padrão é 12 meses; renovamos no vencimento.

`rejected`

A Sumsub rejeitou os documentos. Usuário não pode transacionar. Tem que reenviar (uma submissão nova volta para `pending`).

`expired`

Um KYC `approved` ultrapassou a janela de validade. Usuário precisa verificar de novo antes de transacionar.

O caminho completo

1. Crie o usuário

curl -X POST $BLENDFI_BASE/v1/users \
  -H "Authorization: Bearer $BLENDFI_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "content-type: application/json" \
  -d '{
    "external_id": "seu-usuario-001",
    "name": "Ada Lovelace",
    "cpf": "52998224725"
  }'

O usuário é criado com kyc_status: not_started. O CPF é armazenado criptografado; nunca devolvemos em texto puro.

2. Inicie a submissão de KYC

Essa chamada gera uma URL assinada do WebSDK da Sumsub. É seguro expor para seu usuário final (uso único, TTL curto — geralmente 30 minutos).

curl -X POST $BLENDFI_BASE/v1/users/01J.../kyc \
  -H "Authorization: Bearer $BLENDFI_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

Resposta:

{
  "user_id": "01J...",
  "status": "pending",
  "websdk_url": "https://websdk.sumsub.com/start/eyJ...",
  "websdk_url_expires_at": "2026-04-29T13:30:00Z"
}

O kyc_status do usuário muda para pending imediatamente, antes mesmo dos documentos serem enviados. Esse é o estado de "tem uma submissão em andamento".

Tempo de vida do link WebSDK

O websdk_url é válido até websdk_url_expires_at. Se o usuário final não abrir a tempo, chame POST /v1/users/{id}/kyc de novo para pegar um link novo. O estado da submissão de KYC continua em pending mesmo gerando link novo — você não perde progresso.

3. Redirecione o usuário final para o WebSDK

Abra websdk_url numa aba do navegador, num iframe ou numa webview mobile. A Sumsub guia o usuário pela captura de documentos (CPF + documento de identidade + selfie) e fecha o fluxo.

O usuário não volta pra você com um status — a Sumsub não conhece suas URLs. Você descobre o resultado por webhook (próximo passo) ou fazendo polling em GET /v1/users/{id}/kyc.

4. Receba o resultado por webhook

Quando a Sumsub termina a revisão, ela avisa a BlendFi. A BlendFi atualiza o kyc_status do usuário e encaminha um webhook para sua URL registrada.

{
  "type": "user.kyc.approved",
  "user_id": "01J...",
  "external_id": "seu-usuario-001",
  "kyc_status": "approved",
  "approved_at": "2026-04-29T13:08:00Z",
  "expires_at": "2027-04-29T13:08:00Z"
}

Tipos de evento possíveis: user.kyc.approved, user.kyc.rejected, user.kyc.expired. Não tem evento para pending — esse é o estado quando a submissão começa.

Se você ainda não tem webhooks ligados, faça polling como fallback:

curl $BLENDFI_BASE/v1/users/01J.../kyc \
  -H "Authorization: Bearer $BLENDFI_KEY"
{
  "user_id": "01J...",
  "status": "approved",
  "approved_at": "2026-04-29T13:08:00Z",
  "expires_at": "2027-04-29T13:08:00Z"
}

5. Transacione

Com kyc_status: approved, o usuário pode ser sujeito de uma cotação, transação ou qualquer outro endpoint que movimenta dinheiro. Antes disso, esses endpoints respondem com um erro claro apontando de volta para o passo do KYC.

Forçando resultados de KYC no sandbox

O sandbox usa um espelho da Sumsub. Para evitar esperar uma revisão de documento real, use o test helper para forçar qualquer resultado:

curl -X POST $BLENDFI_BASE/v1/test_helpers/users/01J.../kyc \
  -H "Authorization: Bearer $BLENDFI_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "content-type: application/json" \
  -d '{"status": "approved"}'

Valores aceitáveis: "approved", "rejected", "expired". O webhook é disparado exatamente como seria em produção, então sua lógica de handler é exercitada de ponta a ponta.

Apenas no sandbox

/v1/test_helpers/* não existe em produção — chamadas retornam 404. Garanta que seus caminhos de código que forçam resultados de KYC estejam marcados como test-only e nunca rodem contra api.blendfi.com.

Renovação e expiração

KYCs aprovados valem por 12 meses por padrão. A gente monitora a expiração e move o usuário para kyc_status: expired no dia do limite. Você recebe um webhook user.kyc.expired 7 dias antes da expiração para conseguir avisar o usuário a verificar de novo com antecedência.

Uma reverificação é uma chamada POST /v1/users/{id}/kyc nova — o usuário passa pelo mesmo fluxo do WebSDK de novo. Não tem endpoint separado de "renovação".

Rejeições

Um resultado rejected inclui um rejection_reason:

{
  "user_id": "01J...",
  "status": "rejected",
  "rejected_at": "2026-04-29T13:08:00Z",
  "rejection_reason": "document_unreadable"
}

Razões comuns:

rejection_reasonO que aconteceuO que dizer ao usuário
document_unreadableFotos muito borradas, com reflexo ou cortadasRefazer com luz melhor, documento inteiro no enquadramento
document_expiredO documento enviado está fora da validadeEnviar um documento atual
liveness_failedA selfie não bateu com o documento ou era foto de fotoTentar de novo com o rosto real do usuário na câmera
pep_matchO usuário bateu numa lista de pessoas politicamente expostasA gente escala; você ouve da gente
sanctions_matchO usuário bateu numa lista de sançõesO usuário não pode ser onboardado
data_mismatchOs dados do documento não batem com o CPF / nome no nosso sistemaVerifique seus inputs de external_id, name, cpf

Um usuário rejected pode reenviar (POST /v1/users/{id}/kyc de novo). A submissão nova substitui a rejeição; o status volta para pending.

pep_match e sanctions_match são terminais no nosso fluxo — reenvio não resolve. A gente trata caso a caso com você.

O que ler em seguida

FAQ

O mesmo usuário final pode reenviar se for rejeitado? Pode — para a maioria das razões de rejeição. Chame POST /v1/users/{id}/kyc de novo para pegar um link novo do WebSDK; o usuário passa pelo fluxo de novo. Os dois casos terminais são pep_match e sanctions_match — esses exigem revisão humana do nosso lado.

O que acontece se o usuário fechar o WebSDK no meio? O kyc_status dele continua pending. O WebSDK guarda o estado parcial por uns 24 horas; se ele reabrir o mesmo link nessa janela, retoma de onde parou. Após a expiração, gere um link novo.

Eu preciso verificar a assinatura do webhook? Precisa. Webhooks de produção da BlendFi carregam um cabeçalho X-BlendFi-Signature (HMAC-SHA-256 sobre o corpo, com um segredo por organização). Rejeite qualquer webhook cuja assinatura não bata. A gente fornece snippets de verificação na referência de webhooks.

Por que o estado not_started existe se eu sempre inicio o KYC logo após criar o usuário? Algumas integrações criam usuários cedo (cadastro de waitlist, por exemplo) e só disparam o KYC quando o usuário faz uma ação relevante de dinheiro. O formato em dois passos suporta esse padrão. Se você sempre inicia o KYC na hora, trate not_started como um estado transiente que sua UI nunca exibe.

Posso ver as imagens dos documentos rejeitados? Não. A Sumsub guarda os documentos; a BlendFi só vê o veredicto e a razão da rejeição. Isso é uma fronteira de privacidade por design.

O usuário passou no KYC em outro produto que eu opero — posso pular o KYC da BlendFi para ele? Não. A gente reverifica por organização BlendFi, independente de o mesmo usuário final ter sido verificado em outro lugar. Isso é uma exigência regulatória.

Nesta página