Mapeamento dos status de verificação para os estados do seu produto.

Charles Archibong, Cofundador
Gere o status do seu produto a partir do resultado e armazene `checkStatus` ao lado como explicação. Mapeie cada um dos dez valores de status para um estado em seu próprio sistema e obtenha o status mais recente de `verification.status_updated` ou por meio de polling.

Pontos principais
- Aja de acordo com o status, que é o resultado; mantenha o checkStatus como o registro do que as verificações automatizadas encontraram.
- "Aprovado com falha no checkStatus" é uma exceção registrada, não uma contradição, e vale a pena armazená-la.
- Com regras de decisão de fluxo de trabalho, o status `verification.completed` não é definitivo; o veredicto chega como `verification.status_updated`.
- Apresente ao candidato a justificativa para os resultados de falha e não encontrado, nunca para erros, quando a reclamação for dirigida a você.
Seu produto deve mudar de estado em um campo:statusÉ o resultado de uma verificação e assume um de dez valores, dentre eles:not_startedparaapproved. LojacheckStatusAo lado, ele registra o que as verificações automatizadas encontraram e é a única explicação que você terá quando os dois discordarem. Eles discordam com mais frequência do que os engenheiros esperam, e isso é intencional.
Na prática, isso significa três coisas: mapear cada um dos dezstatuspara definir valores exatamente para um estado em seu próprio sistema, pegue a versão mais recente.statusdoverification.status_updatedwebhook ou por meio de polling, em vez de a partir do primeiro evento recebido, e usereasonCode(nunca apenas o status bruto) para decidir o que dizer ao candidato. O restante deste artigo transforma isso em uma tabela que você pode adotar e um código que você pode adaptar.
Por que existem dois campos em vez de um?
Porque duas coisas diferentes determinam uma verificação. As verificações automatizadas leem o documento, consultam o registro governamental, comparam o reconhecimento facial e leem o chip. Em seguida, as regras de decisão do seu fluxo de trabalho, ou um membro da sua equipe, decidem o que fazer em relação à pessoa. A documentação do ciclo de vida da verificação (abre num novo separador) dedica um campo específico a cada pergunta.
Campo | A pergunta responde | Valores |
|---|---|---|
| Qual é o resultado? |
|
| O que as verificações constataram? |
|
statusé elaborado em uma ordem fixa, e a primeira regra que se aplica prevalece: a decisão de um revisor, depois a decisão do seu fluxo de trabalho e, por fim, as verificações isoladas.checkStatusnunca muda por causa de uma regra ou de um avaliador. Portanto, um candidato cujo rosto não correspondia, mas que foi aprovado por um avaliador após uma videochamada, acaba comstatus: "approved"echeckStatus: "failed"Ambas as afirmações são verdadeiras, e armazenar apenas a primeira impediria que você explicasse posteriormente por que a exceção foi permitida.
Como cada status deve ser associado ao seu produto?
Segue um mapeamento detalhado para um aplicativo de empréstimo ilustrativo. Os estados da conta e as mensagens são exemplos; as colunas da direita representam a parte que deve ser copiada.
| Assentou? | Estado da sua conta (exemplo) | O que o candidato vê (exemplo) | O que seu backend faz |
|---|---|---|---|---|
| Não |
| "Conclua a verificação da sua identidade" | Nada ainda. Envie lembretes se usar links. |
| Não |
| "Retome de onde parou" | Nada ainda. |
| Não |
| "Estamos verificando seus dados" | Espere. Leia. |
| Não |
| "Um membro da nossa equipe está analisando isso." | Espere. Há uma pessoa envolvida. |
| Não |
| O pedido do revisor, além de uma forma de retomar o fluxo. | Aguarde uma nova tentativa. |
| Sim |
| Dê acesso ao produto | Armazene o resultado e continue o processo de integração. |
| Sim |
| Mensagem escolhida de | Decida se uma nova tentativa é permitida. |
| Sim |
| "Comece de novo" | Oferecer uma nova verificação. |
| Sim |
| "Seu link expirou" | Enviar um novo link. |
| Sim |
| Uma mensagem genérica de "algo deu errado" | Tente novamente ou entre em contato com o suporte. Nada foi cobrado. |
Duas opções de design nessa tabela valem a pena copiar, mesmo que você renomeie todos os estados.
Primeiro, um estado por valor, mesmo quando dois valores parecem semelhantes . É tentador dobrar.in_reviewemprocessingPorque ambos significam "espere". Mantenha-os separados:in_reviewSignifica que uma pessoa da sua equipe deve uma decisão, que é uma métrica de fila interna, enquantoprocessingA plataforma está funcionando?
Segundo,declinedé um estado, com a razão que o acompanha . Um documento de identidade que não consta no banco de dados do governo é umdeclinedcomreasonCode: "identity_not_found"Não se trata de um status separado. A ramificação deve ser baseada no código, não em uma proliferação de estados.
O que exatamente o processamento aguarda?
Geralmente, apenas as verificações. Mas quando seu fluxo de trabalho baseia sua decisão em algo mais lento,processingpode durar mais tempo, e o ponto final de status incluiwaitingOnDizer o quê. Os valores incluem"screening"(uma sanção, PEP ou triagem de mídia negativa) e"key_people"(os diretores e proprietários de uma empresa finalizando suas próprias verificações em um pedido de visto);nullSignifica que as verificações ainda estão em execução. A lista de verificação do endpoint de status (abre num novo separador) as inclui.
Esse campo é o que permite que a triagem do seu candidato mostre algo mais útil do que um indicador de carregamento, e permite que sua equipe de operações veja por que uma candidatura comercial foi selecionada.processingpor dois dias.
Por que verification.completed nem sempre é a resposta final?
Porque descreve as verificações, não a decisão. Os eventosverification.completed,.failed,.not_founde.errorsão enviadas assim que as verificações terminam. Se o seu fluxo de trabalho tiver regras de decisão, isso ocorre antes que o fluxo de trabalho tome uma decisão, e suas respectivas regras.statusReflete apenas as verificações.
O veredicto chega em seguida, comoverification.status_updated, comsource: "workflow"O mesmo evento também é acionado quando um revisor toma uma decisão no painel de controle (source: "dashboard") ou seu backend decide por meio da revisão API (source: "api"). Ele carregapreviousStatuse o novostatusE, ao contrário da maioria dos eventos, ele é entregue plano, em vez de embalado em um...dataobjeto, conforme explica a documentação dos webhooks (abre num novo separador) .
Um exemplo prático torna a armadilha concreta. Um fluxo de trabalho rejeita qualquer pessoa com correspondência confirmada na lista de vigilância. Um candidato passa em todas as verificações:verification.completedchega comstatus: "approved"Segundos depois, a espera na triagem se resolve e o fluxo de trabalho diminui, entãoverification.status_updatedchega comstatus: "declined"esource: "workflow"Se o seu responsável integrou o cliente no primeiro evento, você integrou alguém que sua própria política rejeita.
A regra: se o seu fluxo de trabalho tiver regras de decisão, trate-as.verification.status_updated(ou uma nova pesquisa) como fonte destatusSem regras de decisão, as verificações são a decisão everification.completedé definitiva, a menos que um revisor a altere posteriormente.
O que você deve dizer ao candidato?
UsarreasonCodepara escolher a mensagem e usarreasoncom cuidado.
Em umfailedounot_foundverificar,reasonO documento foi redigido para o requerente: linguagem simples, indicando o que não correspondeu e o que fazer em seguida, sem pontuação, sem limite mínimo e sem nenhuma transcrição dos registros governamentais. Você pode apresentá-lo exatamente como está.
Em umerrorresultado,reasonEstá escrito para você. Pode dizer "recarregue seu saldo" ou "entre em contato". Toden ", o que não significa nada para um candidato. Mostre-lhes uma mensagem genérica e encaminhe-os para a próxima etapa.reasonpara sua equipe.
| Próximo passo sugerido para o candidato |
|---|---|
| Tire a foto novamente. |
| Utilize um documento atual. |
| Refaça a selfie |
| Confira o número e os detalhes inseridos. |
| Mensagem genérica de nova tentativa |
Novos códigos podem ser adicionados ao longo do tempo, portanto, associe um código não reconhecido a uma mensagem de falha genérica em vez de a um erro em seu código.
Como isso se traduz em código?
Um manipulador que aplica as regras acima, em TypeScript. OaccountsAs chamadas são espaços reservados para sua própria persistência.
type Status =
| 'not_started' | 'in_progress' | 'processing' | 'in_review'
| 'awaiting_resubmission' | 'approved' | 'declined'
| 'abandoned' | 'expired' | 'error';
const ACCOUNT_STATE: Record<Status, string> = {
not_started: 'kyc_invited',
in_progress: 'kyc_in_progress',
processing: 'kyc_checking',
in_review: 'kyc_manual_review',
awaiting_resubmission: 'kyc_action_needed',
approved: 'kyc_passed',
declined: 'kyc_failed',
abandoned: 'kyc_dropped',
expired: 'kyc_link_expired',
error: 'kyc_retry',
};
export async function applyVerificationStatus(event: {
verificationId: string;
status: Status;
checkStatus?: string;
reasonCode?: string | null;
reason?: string | null;
}) {
const state = ACCOUNT_STATE[event.status] ?? 'kyc_checking'; // unknown value: keep waiting
await accounts.updateByVerificationId(event.verificationId, {
kycState: state,
kycStatus: event.status,
kycCheckStatus: event.checkStatus ?? null, // the explanation, kept for audit
kycReasonCode: event.reasonCode ?? null,
kycReason: event.reason ?? null,
});
}Chame-o de ambos os lados.verification.status_updatedmanipulador e seu caminho de sondagem, para que os dois não divirjam. Elimine entregas de webhook duplicadas noX-Myaza-Deliverycabeçalho antes de chamá-lo.
O que acontece quando uma verificação é enviada de volta?
O sistema mantém seu ID. Quando um avaliador envia uma verificação de volta e o candidato reenvia a inscrição, a mesma verificação inicia uma nova tentativa:attemptaumenta em um,checkStatusretorna apendinge as verificações são executadas novamente. Seu mapeamento lida com isso sem casos especiais: o status passa deawaiting_resubmissionparaprocessinge depois se estabiliza novamente. Digitando seus registros emverificationIdO fato de não se basear em uma consulta de "última verificação para este usuário" é o que faz isso funcionar.
Para ter uma visão completa, incluindo todas as tentativas anteriores e todas as decisões, leiaGET /api/kyc/verifications/:iddo seu backend com uma chave secreta. Ele retornareviewestatusHistory, do mais recente para o mais antigo, conforme descrito na referência do resultado da verificação (abre num novo separador) .
Lista de verificação
Um estado de produto por
statusvalor, comin_revieweprocessingmantidos separados.checkStatus,reasonereasonCodearmazenado ao lado destatus, sempre.Mais recente
statusretirado deverification.status_updatedou realizar pesquisas quando seu fluxo de trabalho tiver regras de decisão.Cópia do candidato escolhida por
reasonCode;reasonexibido apenas emfailedenot_found.Desconhecido
statusoureasonCodeOs valores são tratados como "continuar aguardando" ou "falha genérica", nunca como uma falha grave.Registros com foco em
verificationIdAssim, os novos envios atualizam a mesma linha.
O centro de desenvolvedores vincula o webhook e as referências de status usadas aqui.
Fontes

Charles Archibong
Cofundador
Charles Archibong é cofundador da Toden. Ele escreve sobre verificação de identidade, tecnologia financeira e o trabalho prático de construção de serviços digitais confiáveis.


