Pular para o conteúdo principal

Retorno ao seu app (callbackUri)

Nas jornadas de abertura de conta e de portabilidade, o titular sai do seu app, faz a captura facial (ou a autorização) numa página nossa e, no fim, ficava numa tela de conclusão da CorpX. O campo opcional callbackUri fecha esse ciclo: ao terminar a etapa, o titular é levado de volta para o seu app ou site, e o desfecho vai na própria URI.

Vale para os dois fluxos, porque os dois entram pelo mesmo endpoint:

  • abertura de conta PF (POST /v1/accreditations/pf) e PJ (POST /v1/accreditations/pj);
  • portabilidade automática, que usa o mesmo POST /v1/accreditations/pf.

Pré-requisito: cadastrar a URI

A URI precisa estar registrada previamente para o seu tenant. Fale com o suporte da CorpX informando exatamente a URI (ou as URIs) que você vai usar — quem cadastra é o nosso time.

A comparação é exata. Se você registrar https://app.suaempresa.com/onboarding/done, é essa string que você deve enviar; nós apenas acrescentamos os parâmetros de desfecho no fim. Não há wildcard nem casamento por prefixo: https://app.suaempresa.com/onboarding/done/extra é outra URI e precisa de outro cadastro.

Enviar uma URI que não está cadastrada recusa a criação com 400 invalid_callback_uri — você descobre na hora, e não depois de o titular ter gasto a jornada inteira.

O que é aceito

https://https://app.suaempresa.com/onboarding/done
Esquema do seu aplicativo (deeplink)suaempresa://onboarding/done

O que é recusado

  • http:// sem TLS, e qualquer esquema que o navegador execute ou leia do disco (javascript:, data:, file:, blob:);
  • credenciais embutidas (https://usuario:senha@...);
  • localhost, endereços de rede interna (10.x, 192.168.x, 172.16–31.x, 169.254.x, ::1, fd00::/8) e sufixos locais (.local, .internal);
  • endereço IP literal em https — use nome de domínio;
  • fragmento (#), porque ele encerraria a URI antes dos parâmetros;
  • host sem domínio (https://intranet/).

Como enviar

curl -X POST "https://tenant.api.corpx.com/v1/accreditations/pf" \
-H "Authorization: Bearer {token}" \
-H "X-Tenant-Id: tenant-suaempresa" \
-H "Content-Type: application/json" \
-d '{
"person": { "...": "..." },
"address": { "...": "..." },
"callbackUri": "https://app.suaempresa.com/onboarding/done"
}'

O campo é opcional. Sem ele, nada muda: o titular termina na página de conclusão da CorpX, como antes.

A URI aceita também é devolvida em callbackUri na resposta do POST e no GET /v1/accreditations/{id}.

Parâmetros que chegam na volta

ParâmetroQuandoDescrição
accreditationIdSempreO mesmo accreditationId que você recebeu na criação.
outcomeSempreDesfecho daquela etapa (tabela abaixo).
personIdEtapas de uma pessoa (biometria e aceite)Identificador da pessoa dentro do credenciamento, devolvido em persons[].personId desde a criação. Nunca enviamos CPF na URI: ela fica em histórico de navegador, log de proxy e telemetria de app.
remainingPeopleCredenciamento com mais de uma pessoaQuantas pessoas ainda faltam concluir a etapa. 0 significa que aquela foi a última.

Exemplo de retorno de um sócio de PJ que concluiu a facial e ainda tem um sócio pendente:

https://app.suaempresa.com/onboarding/done?accreditationId=acr_9f8e7d6c5b4a&outcome=biometry_approved&personId=prs_3b1c9a7f2e4d&remainingPeople=1

Vocabulário de outcome

Os desfechos negativos reaproveitam as mesmas strings de errorReason que você já trata nos webhooks.

outcomeQuando acontece
biometry_approvedBiometria facial aprovada.
biometry_pendingA selfie foi enviada e o resultado ainda estava em análise no instante em que o titular voltou. É o caso mais comum — o resultado chega em seguida, pelo webhook.
biometry_failedBiometria facial reprovada. Cabe retry.
biometry_expiredO link de biometria expirou. Cabe retry.
acceptance_recordedAceite do fluxo de biometria própria (BYO) registrado.
acceptance_expiredO link de aceite expirou.
acceptance_blockedAceite barrado na análise de dispositivo.
consent_acceptedO titular autorizou a portabilidade.
consent_declinedO titular recusou.
consent_expiredO link de autorização expirou.
consent_identity_failedA verificação de identidade do titular não foi aprovada.
consent_blockedAutorização barrada na análise de dispositivo.
errorFalha inesperada do nosso lado. Não conclua nada sobre a jornada; consulte o credenciamento.
biometry_approved não é conta ativa

No onboarding, concluir a biometria não conclui o credenciamento: ainda vêm a revisão, a integração com o liquidante e a ativação. biometry_approved com remainingPeople=0 quer dizer que a etapa de biometria terminou — nada além disso.

A conta só está pronta para operar quando chega o webhook accreditation.active (ou o GET /v1/accreditations/{id} responde ACTIVE) com o accountId.

Os parâmetros não são prova de nada

Eles viajam na barra de endereço e o próprio titular pode editá-los. Não há assinatura: são uma dica de interface, para o seu app escolher que tela mostrar quando o usuário voltar.

Qualquer decisão com efeito — liberar acesso, marcar o cadastro como concluído, habilitar uma operação — tem que se apoiar em:

  • o webhook (accreditation.updated, accreditation.active, accreditation.failed), ou
  • uma consulta a GET /v1/accreditations/{accreditationId}.

Trate a volta como "o usuário está de novo no meu app, provavelmente com este resultado" e confirme pelo canal servidor a servidor.

PJ com vários sócios

Cada sócio tem link próprio, então cada um gera o seu próprio retorno, com o personId de quem concluiu. O remainingPeople diz se ainda falta alguém, e exatamente um dos retornos sai com remainingPeople=0.

Duas coisas que valem para o seu app:

  • remainingPeople=0 significa que não há mais pendência, não que todos foram aprovados. Um sócio reprovado pode repetir a biometria, e enquanto ele não repetir ele não conta como pendente. O status individual de cada pessoa vem em persons[].biometryStatus no GET.
  • O desfecho individual (outcome) e o do conjunto (remainingPeople) são informações distintas e chegam juntas de propósito.

Quando o redirect não acontece

O titular termina na nossa página de conclusão, sem erro, quando:

  • a accreditation não tem callbackUri;
  • a URI foi removida da allowlist no meio da jornada — a autorização é reconferida no momento do salto, e a remoção vale na hora;
  • não foi possível montar a URI de retorno.

Nesses casos o credenciamento segue normalmente; só o salto de volta é que não acontece. Como o desfecho de verdade chega por webhook, nada é perdido.

O salto é feito por uma página nossa, com um link visível, e não por redirect HTTP: esquema de aplicativo não atravessa redirect de forma confiável em todos os navegadores. Se o app não estiver instalado, o titular vê o link e a mensagem do desfecho em vez de uma tela de erro do navegador.