Projetando seu produto com base em resultados de verificação assíncrona

Charles Archibong, Cofundador
Considere o envio como o início de uma máquina de estados, não como o fim de uma requisição. Exiba um estado pendente com base no ID de verificação, atualize-o por meio de webhooks e permita que o status mude mais de uma vez.

Pontos principais
- "onSubmit" significa que a verificação foi criada, nunca que ela foi aprovada.
- Aja de acordo com o status e armazene o checkStatus ao lado; eles podem discordar legitimamente.
- O status de uma verificação pode mudar após sua conclusão, portanto, considere a última alteração, não o primeiro evento.
- Ao reenviar o formulário, o mesmo ID de verificação é mantido; atualize o registro em vez de criar um novo.
Entre o envio e o resultado final, seu aplicativo deve estar em um estado pendente, vinculado ao ID de verificação, controlado por eventos do seu backend e preparado para que o status mude mais de uma vez. No momento em que SDK ligaçõesonSubmitInforma que a verificação foi criada. Não informa nada sobre se ela foi bem-sucedida.
Isso parece óbvio até que uma verificação fique em análise por um dia, seja reenviada para uma nova selfie, retorne e seja aprovada. Um produto construído em torno de um único callback de "sucesso ou falha" não tem onde lidar com isso. Um produto construído em torno de uma pequena máquina de estados resolve o problema sem casos especiais.
Por que o resultado não pode chegar junto com o envio?
A verificação de identidade leva tempos diferentes por bons motivos. É preciso ler um documento, consultar um registro governamental, comparar um rosto. Depois, um gráfico de decisão (abre num novo separador) pode ficar aguardando em uma tela de lista de vigilância, uma empresa pode precisar da verificação de seus diretores e um membro da sua equipe pode precisar fazer uma verificação. Algumas dessas etapas levam segundos, outras, dias.
Então Toden Retorna assim que a verificação for criada, com o status deprocessingE informa ao seu backend como a transação será resolvida por meio de webhooks (abre num novo separador) ou de uma consulta de status (abre num novo separador) . A questão de design para o seu produto é o que mostrar e o que permitir durante esse intervalo.
Dois campos, duas perguntas
Cada verificação enviada contém dois campos de status, e você precisa de ambos.
statusé o resultado. É o campo em que você atua e utiliza dez valores ao longo de todo o ciclo de vida:not_started,in_progress,processing,in_review,awaiting_resubmission,approved,declined,abandoned,expiredeerror.
checkStatusFoi isso que as verificações automatizadas constataram:pending,verified,failed,not_foundouerrorAs regras de decisão e os revisores nunca as alteram.
Eles discordam sempre que algo além das verificações é decidido. Uma verificação pode serapprovedcomcheckStatus: "failed"Porque um avaliador aceitou uma selfie que ficou um pouco abaixo da nota de aprovação em condições de pouca luz. Guarde ambas. No dia em que alguém perguntar por que aquele cliente foi autorizado a entrar,checkStatusereasonCodeEssa é a sua resposta.
O status é decidido em uma ordem fixa: primeiro, prevalece a decisão de um revisor; em seguida, a decisão do seu fluxo de trabalho; e, por último, as verificações realizadas pelo próprio revisor.
Mapear o status para o que o usuário vê.
A maioria dos produtos precisa apenas de alguns estados visíveis para o usuário. Um mapeamento a partir dos valores documentados, como ponto de partida:
| O que seu aplicativo mostra | O que seu aplicativo permite |
|---|---|---|
| "Estamos verificando seus dados" | Navegação, não ação restrita |
| "Estamos analisando seus dados; isso pode levar algum tempo." | O mesmo que processar |
| "Precisamos que você refaça uma etapa" com o link. | Somente o reenvio |
| Verificado | A ação controlada |
| Um próximo passo, formulado a partir de | Tente novamente ou entre em contato com o suporte. |
| "Algo deu errado da nossa parte, por favor, tente novamente." | Tentar novamente |
| "Comece de novo" | Um novo link ou uma nova tentativa |
A mesma regra se aplica ao código, já que uma única função pode ser compartilhada entre suas telas:
type UiState = "checking" | "action_needed" | "verified" | "not_verified" | "start_again";
function uiStateFor(status: string): UiState {
switch (status) {
case "approved": return "verified";
case "declined": return "not_verified";
case "awaiting_resubmission": return "action_needed";
case "abandoned":
case "expired":
case "error": return "start_again";
default: return "checking"; // processing, in_review and anything unrecognised
}
}O ramo padrão é intencional. Ele abrangenot_started,in_progress,processingein_reviewE se um valor que você não reconhece chegar a esse ponto, "continuar verificando" é uma resposta mais segura do que simplesmente passar.
Formular uma recusa
Em umfailedounot_foundresultado,reasonÉ uma frase escrita para o candidato, sem pontuações ou limites mínimos, e você pode apresentá-la tal como está.reasonCodeé o token estável para ramificar:document_expiredpode acionar "Carregar um documento atual",selfie_mismatchum lembrete para refazer a selfie com melhor iluminação. Em umerrorresultado oreasonSe a mensagem for dirigida a você, por exemplo, sobre seu saldo de crédito, mostre à pessoa uma mensagem genérica e encaminhe o motivo para sua equipe.
Diferenciar "alguns segundos" de "alguns dias"
processingAbrange tanto a leitura de um documento quanto uma decisão mantida em uma tela de lista de observação. O endpoint de statuswaitingOnO campo indica qual:nullenquanto as verificações ainda estiverem em andamento,"screening","key_people"para uma empresa que aguarda seus diretores e proprietários, ou"address_presence"Para uma verificação de endereço que leva vários dias, quando ativada, use-a para definir expectativas ("isso geralmente termina em um minuto" em vez de "enviaremos um e-mail para você") e trate um valor desconhecido como uma espera da qual você ainda não aprendeu.
Em qual sinal confiar e quando?
Chegam até você três sinais, e eles não têm a mesma autoridade.
O sinal do cliente. O SDK 's
onSubmitou de uma página hospedadasubmittedO evento é acionado quando o solicitante conclui o fluxo. Use-o para mover o usuário imediatamente para a tela de pendências. Não o utilize para conceder nenhuma permissão.Webhooks para o seu backend. Estes são os registros. Atualize seu banco de dados a partir deles e envie a alteração para a tela do usuário a partir daí.
O ponto final de status.
GET /api/kyc/status/:verificationIdRetorna o status atual com uma chave publicável e não contém dados pessoais, pontuações ou resultados. Use-o para preencher uma lacuna, por exemplo, quando o aplicativo é reaberto antes que o seu servidor tenha enviado qualquer atualização.
O primeiro webhook nem sempre é o último.
Se o seu fluxo de trabalho tiver regras de decisão,verification.completedé enviado quando as verificações terminam, antes que o fluxo de trabalho seja decidido. Seustatusreflete apenas as verificações. O veredicto do fluxo de trabalho chega posteriormente comoverification.status_updatedcomsource: "workflow"E esse é o status sobre o qual se deve agir. Posteriormente, um revisor pode decidir ou alterar uma decisão anterior, e cada alteração chega como outra.verification.status_updated.
As entregas são feitas de forma independente e podem chegar fora de ordem, portanto, mantenha o controle.changedAtdo troco que você detém e ignore qualquer troco mais antigo. Sem regras de decisão, as verificações são a decisão e o status emverification.completedA avaliação permanece válida a menos que um revisor a altere posteriormente.
Os reenvios mantêm o mesmo ID.
Quando um revisor envia uma verificação de volta, o candidato refaz apenas as etapas solicitadas, e seu novo envio completa a mesma verificação. Você recebe outro evento de resultado com o mesmo conteúdo.verificationId,attemptcontaram echeckStatusvoltar parapendingEnquanto as verificações são processadas novamente, atualize o registro que você possui. Criar uma nova linha para cada evento resultaria em dois clientes onde há apenas um.
Se for mesmo necessário, faça uma votação.
Os webhooks devem ser usados em produção. O polling serve para situações de vulnerabilidade: uma tela de celular que reabre ou um ambiente onde você ainda não pode receber webhooks. Se você usar polling:
Reduza a distância, começando com alguns segundos e aumentando gradativamente, e pare assim que a situação se estabilizar.
Lembre-se do limite padrão documentado de 100 solicitações a cada 15 minutos por cliente e leia o
RateLimit-RemainingeRateLimit-ResetEm vez de adivinhar, use cabeçalhos.Faça a pesquisa no menor número possível de locais. Uma dúzia de telas abertas, cada uma consultando a mesma verificação, gera uma dúzia de vezes mais tráfego para uma única resposta.
Tentativas de refazer a caminho
A lacuna também existe no lado do envio. Uma rede móvel descarta a resposta à chamada de criação e o aplicativo não sabe se a verificação existe. Envie um estável.metadata.requestIdPara cada verificação lógica, reutilize-a em qualquer nova tentativa. API Retorna a verificação existente em vez de criar uma segunda e nunca cobra duas vezes.
Um passeio guiado
Considere um aplicativo hipotético de poupança com um fluxo de trabalho que verifica cada usuário cadastrado. Um solicitante envia uma solicitação pelo celular às 9h. O aplicativo recebeonSubmite exibe "Estamos verificando seus dados". Segundos depois, o sistema recebeverification.completedcomcheckStatus: "verified". Isso éstatuslêapproved, porque esse evento reflete apenas as verificações, então o backend ainda não concede nada: o fluxo de trabalho ainda está aguardando na tela e uma verificação de status mostraprocessingcomwaitingOn: "screening"A tela retorna uma possível correspondência, o fluxo de trabalho a encaminha para revisão everification.status_updatedchega comin_reviewO aplicativo altera sua mensagem para informar que a revisão pode demorar mais. Às 14h30, um responsável pela conformidade remove o falso positivo e aprova; um segundoverification.status_updatedchega comapprovedE o sistema interno permite depósitos e envia notificações push.
Nada nessa sequência precisou de tratamento especial. É um único registro, indexado por um único ID, atualizado por cada evento subsequente.
Uma lista de verificação para o seu estado pendente
Crie um registro local com a chave em
verificationIdo momentoonSubmitincêndios.Atualize somente a partir do seu painel administrativo, por meio de webhooks.
Aja sobre
status; lojacheckStatus,reasonereasonCodeao lado.Fique por dentro das últimas novidades
changedAte ignore as alterações mais antigas.Tratar status desconhecido e
waitingOnvalores como "ainda verificando".Ao reenviar o documento, atualize o mesmo registro e mostre a tentativa.
A palavra declina de
reasonCodee nunca mostre umerrormotivo para o requerente.Reutilizar
requestIdem novas tentativas, e realizar sondagens apenas para preencher lacunas.
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.


