> For the complete documentation index, see [llms.txt](https://docs.4p.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.4p.finance/parceiro/abertura-de-conta-kyc-kyb.md).

# Abertura de Conta (KYC/KYB)

Este documento descreve, passo a passo, as rotas que um parceiro deve consumir para realizar o fluxo completo de abertura de conta (KYC) na 4Pay a partir do frontend do parceiro.

***

## 1. Visão Geral

Esta API permite que um parceiro construa seu próprio frontend de cadastro e conduza o cliente final por todo o fluxo de abertura de conta na 4Pay, incluindo validação de identidade (KYC) e liveness.

O fluxo é composto por múltiplas etapas sequenciais. Cada etapa deve ser concluída com sucesso antes de avançar para a próxima.

### 1.1 Endereços Base

**Laboratório (sandbox):** `https://verify-api.4p.finance/lab/`

{% hint style="warning" %}
**⚠️ Acesso ao ambiente de laboratório**

O ambiente de laboratório exige liberação prévia de IP em whitelist. Envie o(s) IP(s) de origem das requisições para a equipe 4Pay antes de iniciar os testes.
{% endhint %}

**Produção:** `https://verify-api.4p.finance/`

{% hint style="warning" %}
**🔑 Partner ID — somente em produção**

O segmento de Partner ID (hash que identifica o parceiro) é usado apenas no ambiente de produção. No laboratório, as rotas são chamadas diretamente após `/lab/`, sem esse segmento.
{% endhint %}

```
ex. (laboratório): https://verify-api.4p.finance/lab/account/initial_registration
ex. (produção):    https://verify-api.4p.finance/v1/{hash-partner-id}/account/initial_registration
```

Nas seções seguintes, o path de cada rota é mostrado de forma relativa (ex.: `/account/initial_registration`). Monte a URL completa combinando com o endereço base do ambiente e, em produção, adicionando o Partner ID logo após o domínio.

### 1.2 Formato Padrão de Resposta

Todas as respostas da API seguem o mesmo formato-base. O campo mais importante para tratar a resposta programaticamente é sempre `info.result` — ele identifica de forma única o resultado da operação, independentemente do valor de `success` ou `http_code`.

```json
{
  "http_code": 200,
  "success": true,
  "info": {
    "result": "identificador_do_resultado",
    "message": "Mensagem legível para exibir ou logar.",
    "data": {}
  }
}
```

{% hint style="info" %}
**💡 Dica de integração**

Trate sempre a lógica da sua aplicação com base em `info.result`, não apenas em `success` ou `http_code`. Isso porque um `http_code` 200 pode conter tanto sucesso quanto falha de regra de negócio (ex.: documento já cadastrado). O campo `message` é amigável e pode ser exibido diretamente ao usuário final quando fizer sentido.
{% endhint %}

### 1.3 Arquitetura de Integração

{% hint style="info" %}
**🌐 Chamadas diretas do browser — sem backend intermediário**

O frontend do parceiro deve requisitar a API da 4Pay diretamente do browser do cliente final, sem passar por um servidor/backend do parceiro como intermediário. Essa é uma exigência de arquitetura: é o que possibilita à 4Pay aplicar controle de IP e análises de risco via WAF diretamente sobre o tráfego do usuário final (ex.: listas de reputação de IP, detecção de proxy/VPN/datacenter, rate limiting por usuário). Se as requisições passarem pelo backend do parceiro, essa visibilidade se perde.
{% endhint %}

As rotas descritas neste documento são específicas do parceiro e possuem CORS liberado apenas para o domínio informado no cadastro da integração.

### 1.4 Autenticação — reCAPTCHA v3

{% hint style="warning" %}
**🔒 Escopo do reCAPTCHA**

Apenas a primeira rota do fluxo — `/account/initial_registration` — exige o token do reCAPTCHA v3 (campo `rid`). As demais rotas do fluxo não requerem esse token.
{% endhint %}

O token deve ser gerado no frontend do parceiro com o site key exclusivo fornecido pela 4Pay para esse parceiro.

* O domínio autorizado a gerar tokens com esse site key é restrito ao domínio do parceiro cadastrado.
* O token é validado no backend da 4Pay (score mínimo e ação esperada).\
  \
  [Veja a documentação do reCAPTCHA v3](https://developers.google.com/recaptcha/docs/v3?hl=pt-br)

### 1.5 Visão Geral do Fluxo

As etapas abaixo devem ser executadas nesta ordem:

1. Cadastro inicial (e-mail e senha) — envia e-mail de confirmação de posse do e-mail
2. Validação da hash de abertura de conta — confirma que a hash da URL recebida por e-mail é válida
3. Envio do documento (CPF/CNPJ) — verifica se já existe conta com esse documento
4. Solicitação do código de verificação de telefone (WhatsApp ou SMS)
5. Validação do código de verificação enviado ao telefone
6. Envio dos dados de endereço
7. Início do processo de liveness (validação facial)
8. Envio do documento de identidade (KYC)
9. Verificação do status final da conta / KYC

***

## 2. Cadastro Inicial

Primeira etapa do fluxo. Cria o cadastro inicial do cliente com e-mail e senha.

#### **`POST`** `/account/initial_registration`

{% hint style="info" %}
**📧 O que acontece após essa chamada**

Um e-mail é enviado ao cliente com um link de confirmação. O cliente precisa clicar nesse link para validar que é o dono do e-mail e continuar o cadastro. O link contém um parâmetro `h` (hash) que identifica essa abertura de conta — esse hash será reutilizado nas próximas etapas.
{% endhint %}

**Payload (body)**

```json
{
  "email": "cliente@example.com",
  "password": "SenhaForte@123",
  "newsletter": 1,
  "rid": "0cAFcW"
}
```

**Resposta — Sucesso**

```json
{
  "http_code": 200,
  "success": true,
  "info": {
    "result": "successful_registration",
    "message": "Successful registration."
  }
}
```

Campos do payload: `email` (e-mail do cliente), `password` (senha escolhida pelo cliente — ver requisitos abaixo), `newsletter` (1 = aceite de comunicações, 0 = recusa), `rid` (token do reCAPTCHA v3).

**Requisitos de senha**

A senha informada no campo `password` deve atender a todos os critérios abaixo:

* Mínimo de 6 caracteres.
* Máximo de 20 caracteres.
* Combinação de letras maiúsculas e minúsculas.
* Pelo menos um caractere especial (ex.: !, @, #, $).
* Pelo menos um número.

***

## 3. Validação da Hash de Abertura de Conta

Executada quando o cliente acessa a URL recebida por e-mail (após clicar no link de confirmação). Valida se a hash daquela abertura de conta existe e retorna os dados já cadastrados até o momento.

#### **`GET`** `/account/customer_hash/{hash}`

{% hint style="info" %}
**🔑 Sobre a hash**

É a mesma hash usada em todas as demais etapas do fluxo — recebida no parâmetro `h` da URL de confirmação enviada por e-mail. Aqui ela é enviada diretamente no path da URL, não no body.
{% endhint %}

**Resposta — Hash encontrada**

A hash é válida. O campo `data` traz os dados já cadastrados do cliente até o momento, incluindo o progresso do KYC (`status_kyc` e `step_kyc`).

```json
{
  "http_code": 200,
  "success": true,
  "info": {
    "result": "customer_by_hash",
    "message": "Select Customer by Hash.",
    "data": {
      "email": "cliente@example.com",
      "hash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
      "status_kyc": 0,
      "step_kyc": 4
    }
  }
}
```

**Resposta — Hash não encontrada**

Não existe abertura de conta com essa hash (pode ter expirado, já ter sido concluída, ou ser inválida).

```json
{
  "http_code": 200,
  "success": true,
  "info": {
    "result": "customer_hash_empty",
    "message": "Data not found."
  }
}
```

***

## 4. Envio do Documento (Verificação de Existência)

Etapa executada assim que o cliente clica no link recebido por e-mail e preenche o CPF ou CNPJ no formulário do parceiro. Essa chamada verifica se já existe uma conta 4Pay associada a esse documento.

#### **`POST`** `/account/update_customer`

{% hint style="info" %}
**🔑 Sobre o hash**

O hash é o identificador único e temporário dessa abertura de conta. Ele vem no parâmetro `h` da URL enviada por e-mail (ex.: `https://lab-app.4p.finance/complete-registration?h=a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6`) e deve ser reaproveitado em todas as etapas seguintes do fluxo. Esse hash é invalidado automaticamente assim que a conta é concluída.
{% endhint %}

**Payload (body)**

```json
{
  "person_document": "111.222.333-44",
  "hash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
  "step_kyc": 1
}
```

**Resposta — Documento não encontrado (pode prosseguir)**

Não existe conta com esse documento. O cadastro pode continuar normalmente.

```json
{
  "http_code": 200,
  "success": true,
  "info": {
    "details": {
      "result": "document_not_found",
      "message": "Document not found."
    }
  }
}
```

**Resposta — Documento já cadastrado**

Já existe uma conta 4Pay com esse documento. O fluxo deve ser interrompido e o cliente informado.

```json
{
  "http_code": 200,
  "success": false,
  "info": {
    "details": {
      "result": "document_already_exists",
      "message": "The document sent already exists in the database."
    }
  }
}
```

Campos do payload: `person_document` (CPF ou CNPJ, sempre formatado/com máscara — ex.: `111.222.333-44`), `hash` (identificador da abertura de conta), `step_kyc` (fixo em 1 nesta etapa).

{% hint style="warning" %}
Atenção: nesta rota específica, o resultado vem em `info.details.result` (não em `info.result` como nas demais rotas).
{% endhint %}

***

## 5. Solicitação do Código de Verificação do Telefone

{% hint style="warning" %}
**⏱️ Expiração do código**

O código de verificação enviado por WhatsApp ou SMS expira em 5 minutos. Após esse prazo, é necessário solicitar um novo código.
{% endhint %}

{% hint style="success" %}
**✅ WhatsApp é o canal preferencial**

A validação via WhatsApp é o método recomendado e possui aproximadamente 99% de sucesso de entrega. O SMS é oferecido como alternativa, mas costuma apresentar problemas de recebimento — utilize-o apenas como fallback caso o WhatsApp não esteja disponível para o número do cliente.
{% endhint %}

Envia um código de verificação para o telefone do cliente via WhatsApp. Canal recomendado.

#### **`POST`** `/account/verification_code`

**Payload (body)**

```json
{
  "hash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
  "phone": "5511999998888",
  "type_message": "whatsapp" // "whatsapp" ou "sms"
}
```

**Resposta — Código enviado**

```json
{
  "http_code": 200,
  "success": true,
  "info": {
    "result": "code_sent",
    "message": "Verification code successfully sent.",
    "userdata": {
      "phone": "5511999998888"
    }
  }
}
```

***

## 6. Validação do Código de Verificação

Valida o código recebido pelo cliente via WhatsApp ou SMS.

#### **`POST`** `/account/validation_code`

**Payload (body)**

```json
{
  "hash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
  "phone_only_number": "5511999998888",
  "confirmation_code": "123456"
}
```

**Resposta — Código válido**

```json
{
  "http_code": 200,
  "success": true,
  "info": {
    "result": "valid_code",
    "message": "The code sent is the same as the code generated."
  }
}
```

**Resposta — Código inválido**

```json
{
  "http_code": 200,
  "success": false,
  "info": {
    "result": "invalid_code",
    "message": "The code sent is the same as the code generated."
  }
}
```

## 7. Envio dos Dados de Endereço

Envia os dados de endereço e demais dados cadastrais complementares do cliente.

#### **`POST`** `/account/update_customer`

{% hint style="info" %}
**📌 Mesma rota da Etapa 4**

Esta é a mesma rota `/account/update_customer` usada na Etapa 4, porém com um payload mais completo e `step_kyc = 4`, indicando avanço no fluxo de KYC.
{% endhint %}

**Payload (body)**

```json
{
  "person_type": "personal", // "personal" para Pessoa Física e "empresarial" para Pessoa Jurídica.
  "person_document": "111.222.333-44", // CPF ou se caso for Pessoa Jurídica envia CNPJ.
  "legal_representative_document": "111.222.333-44", // Envia o CPF do representante legal se person_type for Pessoa Jurídica.
  "company_website": "example.com", // Opcional.
  "company_activity": "E-commerce", // Opcional.
  "post_code": "01310100",
  "address": "Rua das Flores",
  "number_address": "123",
  "neighborhood": "Jardim Exemplo",
  "city": "São Paulo",
  "state": "SP",
  "hash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
  "complement_address": "",
  "status_kyc": 0,
  "step_kyc": 4
}
```

**Resposta — Sucesso**

```json
{
  "http_code": 200,
  "success": true,
  "info": {
    "result": "registration_completed",
    "message": "Registration completed successfully.",
    "data": {
      "hash": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
    }
  }
}
```

Campo `person_type` aceita dois valores: `"personal"` (pessoa física) ou `"empresarial"` (pessoa jurídica).

{% hint style="danger" %}
**🚨 Importante — não é o fim do cadastro**

Apesar do result retornar `registration_completed`, o cadastro ainda não está finalizado. A próxima etapa obrigatória é iniciar o processo de liveness.
{% endhint %}

***

## 8. Início do Processo de Liveness

Solicita a URL de liveness (validação facial) do cliente, via integração com a Didit.

#### **`POST`** `/account/liveness`

**Payload (body)**

```json
{
  "hash": "a1b2g3d4e5f6n1b8c9d0e1f2a3b4c5d6"
}
```

**Resposta — Sucesso**

```json
{
  "http_code": 200,
  "success": true,
  "info": {
    "result": "liveness_initiated",
    "message": "Liveness process initiated.",
    "data": {
      "required": true,
      "selfie": false,
      "token": "aBcD1234EfGh",
      "sessionId": "11111111-2222-3333-4444-555555555555",
      "url": "https://verify.4payfinance.com/pt-BR/session/abcd123",
      "kyc_provider": false,
      "registration_step": "doc"
    }
  }
}
```

{% hint style="info" %}
**🎥 Como executar o liveness**

A URL retornada em `data.url` deve ser aberta utilizando o SDK Web ou o SDK Mobile da Didit ([Documentação/SDK Didit](https://docs.didit.me/integration/web-sdks/overview)). Caso o cliente esteja no computador, ele pode escanear um QR Code e concluir o liveness pelo celular, retornando em seguida ao fluxo no computador — ou, se estiver iniciando o cadastro diretamente pelo celular, conclui tudo no próprio dispositivo.\
\
ATENÇÃO: No desktop, utilizando o SDK da Didit, seu frontend monitora a conclusão do liveness e envia o usuário para a próxima etapa de envio do documento.
{% endhint %}

***

## 9. Envio do Documento de Identidade (KYC)

Após a conclusão do liveness, o cliente envia a imagem do documento de identidade.

#### **`POST`** `/account/complete_kyc`

**Arquivo (multipart/form-data)**

Envie as Keys "files" para o arquivo  e "customer" contendo o Value com um JSON para a hash da conta.

**Exemplo multipart/form-data:**

```json
files: <document — PDF, JPG ou PNG>
customer: {"hash": "1464703ee9c1cec3958a6154502818e6"}
```

<mark style="color:$danger;">**ATENÇÃO:**</mark>&#x20;

* O arquivo do documento deve ser renomeado para "document" caso não tenha esse nome.
* Deve conter a FOTO e CPF (preferencialmente CNH) para que seja feita o Face Match, OCR e Documentoscopia para validação dos dados e KYC.

{% hint style="warning" %}
**📷 Qualidade da imagem**

A imagem do documento deve ser enviada em boa qualidade — nítida, bem iluminada, sem cortes ou reflexos. Imagens de baixa qualidade aumentam a chance de reprovação no KYC (ex.: `kyc_data_is_invalid`).
{% endhint %}

***

## 10. Verificação do Status Final da Conta / KYC

Consulta o status final da conta após a conclusão do envio do documento de KYC.

#### **`POST`** `/account/kyc_validation`

**Payload (body)**

```json
{
  "hash": "a1b2c3d4e5f1a7b8c0a0e1f2a3b4c5d5"
}
```

**Resposta — Tudo certo (conta aprovada)**

Após esta chamada, se a conta estiver completa e validada, o cliente recebe um e-mail de confirmação de abertura de conta na 4Pay.

```json
{
  "http_code": 200,
  "success": true,
  "info": {
    "result": "all_data_is_valid",
    "message": ""
  }
}
```

**Respostas — Conta não aprovada / dados inválidos**

Nestes casos, o campo `info.result` identifica o motivo específico da reprovação:

| info.result             | O que significa                                                           |
| ----------------------- | ------------------------------------------------------------------------- |
| `account_not_approved`  | A conta não pôde ser aprovada neste momento.                              |
| `invalid_data`          | Dados enviados durante o cadastro são inválidos, de forma geral.          |
| `invalid_owner_data`    | Dados do titular da conta (pessoa física) são inválidos.                  |
| `invalid_company_data`  | Dados da empresa (pessoa jurídica) são inválidos.                         |
| `kyc_data_is_invalid`   | Os dados extraídos do processo de KYC (documento/liveness) são inválidos. |
| `basic_data_is_invalid` | Dados básicos do cadastro são inválidos.                                  |
| `all_data_is_invalid`   | Todos os dados enviados são inválidos.                                    |

Exemplo de resposta de reprovação:

```json
{
  "http_code": 200,
  "success": false,
  "info": {
    "result": "account_not_approved",
    "message": "This account could not be approved at this time."
  }
}
```
