Skip to content

🌐 Validação Externa de Cadastro de Cliente

📋 Visão Geral

O módulo de validação externa de cliente permite integrar um serviço externo ao fluxo de cadastro e atualização de clientes, habilitando regras de negócio personalizadas como políticas antifraude, validações fiscais ou restrições específicas do negócio.

A validação é executada de forma síncrona (hard-fail) — se o serviço externo rejeitar a operação, o cadastro ou atualização é bloqueado e o erro é propagado para o consumidor da API.

OperaçãoAçãoDescrição
Cadastro 🆕createChamada antes da criação de um novo cliente
Atualização ✏️updateChamada antes da atualização de um cliente existente
Quando a URL do setting está vazia ou ausente, a validação é silenciosamente ignorada sem impacto no fluxo normal.

---

🔄 Fluxo de Execução

1. O payload do cliente é sanitizado (campo password é removido antes do envio) 2. A URL do serviço externo é carregada a partir do setting customers/validation/external-url 3. O serviço externo é chamado via POST com o payload completo do cliente 4. ✅ Se aprovado (status: ok): o fluxo de cadastro/atualização continua normalmente 5. ❌ Se rejeitado (HTTP 4xx): a operação é bloqueada e o erro é propagado 6. 📝 Em caso de falha, um log técnico é persistido para auditoria

---

📤 Contrato de Requisição

O serviço externo recebe um POST com o seguinte payload:

Exemplo para operação create

1{
2 "operation": "create",
3 "domain": "sua-loja.com.br",
4 "customer": {
5 "email": "joao.silva@email.com.br",
6 "nameCorporateName": "João Silva",
7 "tradeName": "João Silva",
8 "isCorporate": false,
9 "gender": "M",
10 "nationality": "brasileiro",
11 "birthdate": "1990-01-15",
12 "phone": "+5511987654321",
13 "origin": "frontend",
14 "documents": [
15 {
16 "type": "cpf",
17 "document": "123.456.789-00"
18 }
19 ],
20 "active": true,
21 "additionalFields": [
22 {
23 "code": "inscricao-estadual",
24 "value": "123456789"
25 }
26 ]
27 }
28}

Exemplo para operação update

Na atualização, o payload é o merge entre os dados atuais do cliente e os novos dados enviados. Isso significa que campos não alterados também estarão presentes:

1{
2 "operation": "update",
3 "domain": "sua-loja.com.br",
4 "customer": {
5 "id": 789,
6 "salesChannelId": 1,
7 "tradePolicyId": 1,
8 "email": "joao.silva@email.com.br",
9 "dealerGroupId": null,
10 "nameCorporateName": "João Silva",
11 "tradeName": "João Silva",
12 "isCorporate": false,
13 "gender": "M",
14 "nationality": "brasileiro",
15 "birthdate": "1990-01-15",
16 "phone": "+5511987654321",
17 "walletAmount": 0,
18 "pointSystemAmount": 0,
19 "orderQuantity": 5,
20 "cancelledOrderQuantity": 0,
21 "orderValue": 1250.00,
22 "lastOrder": null,
23 "origin": "frontend",
24 "createdAt": "2025-06-10 14:30:00",
25 "active": true,
26 "deleted": false,
27 "masked": false,
28 "addresses": [
29 {
30 "id": 123,
31 "zipCode": "01001-000",
32 "recipient": "João Silva",
33 "street": "Praça da Sé",
34 "number": "100",
35 "district": "Sé",
36 "city": "São Paulo",
37 "state": "São Paulo",
38 "stateCode": "SP",
39 "countryCode": "BRA",
40 "complement": "Apto 1"
41 }
42 ],
43 "documents": [
44 {
45 "type": "cpf",
46 "document": "123.456.789-00"
47 }
48 ],
49 "flags": null,
50 "additionalFields": [
51 {
52 "code": "inscricao-estadual",
53 "value": "123456789"
54 }
55 ]
56 }
57}

📊 Campos do payload

CampoTipoPresente emDescrição
operationstringambosOperação: create ou update
domainstringambosDomínio do canal de venda
customer.emailstringambosE-mail do cliente
customer.nameCorporateNamestringambosNome ou razão social
customer.tradeNamestringambosSobrenome ou nome fantasia
customer.isCorporatebooleanambosIndica se é pessoa jurídica
customer.genderstringambosGênero: male, female, undefined
customer.nationalitystringambosNacionalidade
customer.birthdatestringambosData de nascimento (YYYY-MM-DD)
customer.phonestringambosTelefone com DDI
customer.originstringambosOrigem do cadastro (frontend, admin, etc)
customer.documentsarrayambosLista de documentos do cliente
customer.documents.*.typestringambosTipo do documento (cpf, cnpj, rg, ie)
customer.documents.*.documentstringambosNúmero do documento
customer.activebooleanambosStatus de ativação
customer.additionalFieldsarrayambosCampos adicionais personalizados
customer.additionalFields.*.codestringambosCódigo do campo adicional
customer.additionalFields.*.valuemixedambosValor do campo adicional
customer.idintegerupdateID do cliente
customer.salesChannelIdintegerupdateCanal de venda de origem
customer.tradePolicyIdintegerupdatePolítica comercial
customer.dealerGroupIdintegerupdateID do grupo de revendedor
customer.walletAmountnumberupdateSaldo da carteira
customer.pointSystemAmountnumberupdateSaldo do sistema de pontos
customer.orderQuantitynumberupdateQuantidade de pedidos
customer.cancelledOrderQuantitynumberupdateQuantidade de pedidos cancelados
customer.orderValuenumberupdateValor total dos pedidos
customer.lastOrderobject\nullupdateÚltimo pedido do cliente
customer.createdAtstringupdateData de cadastro
customer.deletedbooleanupdateSe o cliente foi excluído
customer.maskedbooleanupdateSe os dados estão mascarados
customer.addressesarray\nullupdateEndereços do cliente
customer.flagsobject\nullupdateFlags do cliente
> ⚠️ O campo password é automaticamente removido do payload antes do envio ao serviço externo.

---

✅ Contrato de Resposta — Sucesso

1{
2 "status": "ok"
3}

O serviço deve retornar HTTP 200 com "status": "ok" para aprovar a operação.

---

❌ Contrato de Resposta — Rejeição de Negócio

1{
2 "error": "Cadastro reprovado por política antifraude."
3}

O serviço deve retornar HTTP 4xx (recomendado 422) com ao menos um dos seguintes campos de mensagem:

CampoObrigatórioDescrição
error \message \errorMessage✅ Sim (ao menos um)Mensagem descritiva do erro que será propagada ao consumidor da API
O erro propagado terá o código interno UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_REJECTED com a mensagem extraída da resposta do serviço externo.

---

⚠️ Erros de Infraestrutura Externa

Falhas de comunicação são tratadas como hard-fail e bloqueiam a operação:

Código InternoHTTPCenário
UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_TIMEOUT504O serviço não respondeu no tempo limite (5s)
UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_UNAVAILABLE502Erro de conexão ou erro 5xx no serviço
UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_INVALID_CONTRACT502HTTP 200 mas o corpo não contém "status": "ok"
UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_REJECTED422O serviço rejeitou a operação (HTTP 4xx)
---

📝 Logs de Auditoria

Todas as chamadas que resultam em falha são registradas na tabela customer_external_validation_log com:

CampoDescrição
customer_idID do cliente (quando disponível)
trade_policy_idPolítica comercial
sales_channel_idCanal de venda
operationOperação: create ou update
urlURL chamada
http_statusCódigo HTTP retornado
request_time_msTempo de resposta em milissegundos
requestPayload enviado (dados sensíveis mascarados)
responseCorpo da resposta
error_typeClassificação: connection, server, timeout, business, contract
Registros com mais de 3 meses são removidos automaticamente.

🔒 Mascaramento de Dados

Os seguintes campos são mascarados antes da persistência do log:

  • customer.tradeName e customer.nameCorporateName — nome mascarado
  • customer.email — e-mail mascarado (ex: cl*@exemplo.com)
  • customer.phone — telefone mascarado (ex: +5578)
  • customer.documents..document — documento mascarado (ex: ..-)
  • ---

    ⚙️ Configuração

    SettingDescrição
    customers/validation/external-urlEndpoint completo para validação externa de cliente (create/update)

    📌 Requisitos do Serviço Externo

  • Deve aceitar requisições POST com Content-Type: application/json
  • Deve responder em até 5 segundos (timeout de conexão e resposta)
  • Deve retornar Content-Type: application/json
  • Deve retornar {"status": "ok"} para aprovar ou HTTP 4xx para rejeitar
  • ---

    🔗 Endpoints Relacionados

    EndpointDescrição
    POST /customersCadastro de cliente (dispara validação com operation: create)
    PUT /customers/{customerId}Atualização de cliente (dispara validação com operation: update)
    POST /customerCadastro de cliente via API pública (dispara validação com operation: create)
    PUT /customerAtualização de cliente via API pública (dispara validação com operation: update)
    GET /customers/external-validation-logsListagem de logs técnicos de validação externa
    ---

    📌 Notas e Considerações

  • A validação opera em modo hard-fail: qualquer falha bloqueia o cadastro ou a atualização do cliente
  • O campo password é sempre removido do payload antes do envio ao serviço externo
  • A mesma URL de serviço é utilizada para ambas as operações (create e update), diferenciadas pelo campo operation no payload
  • Os logs são persistidos apenas para chamadas com falha — operações aprovadas não geram registro de log
  • O serviço externo recebe o payload completo do cliente, incluindo documentos e endereços, permitindo validações complexas

Listagem de Logs de Validação Externa de Cliente

GET /customers/external-validation-logs

Endpoint responsável por listar logs técnicos de validação externa de cliente

Descrição

Retorna uma listagem paginada dos logs técnicos gerados quando a validação externa de cliente falha.

O endpoint é voltado ao painel administrativo e permite auditoria operacional por operação (create ou update), tipo de erro, status HTTP retornado pelo provedor externo e tempo de resposta.

Parâmetros

Headers Obrigatórios

HeaderValorDescrição
AuthorizationBearer {token}Token de autenticação de usuário

Campos de Condição Disponíveis

CampoTipoDescrição
idintegerFiltrar pelo ID do log
tradePolicyIdintegerFiltrar pela política comercial
salesChannelIdintegerFiltrar pelo canal de venda
urlstringFiltrar pela URL chamada no provedor externo
operationstringFiltrar por operação (create ou update)
errorTypestringFiltrar por tipo de erro (contract, connection, timeout, business, server)
httpStatusintegerFiltrar pelo status HTTP retornado pelo provedor externo
requestTimeMsintegerFiltrar pelo tempo de resposta em milissegundos
requeststringFiltrar pelo payload registrado
responsestringFiltrar pela resposta registrada
createdAtstringFiltrar pela data de criação do log

Campos de Ordenação Disponíveis

CampoDescrição
idOrdenar pelo ID do log
operationOrdenar pela operação
errorTypeOrdenar pelo tipo de erro
httpStatusOrdenar pelo status HTTP
requestTimeMsOrdenar pelo tempo de resposta
createdAtOrdenar pela data de criação

Exemplo de Requisição

1curl --request GET \
2 --url '{{MAIN_URL}}/customers/external-validation-logs?limit=20&offset=0&condition[operation]=create&order[0][field]=createdAt&order[0][direction]=desc' \
3 --header 'Authorization: Bearer SEU_TOKEN_AQUI'

✅ Resposta de Sucesso

HTTP Status: 200 OK

1{
2 "status": true,
3 "data": {
4 "registers": [
5 {
6 "id": 19,
7 "customerId": null,
8 "tradePolicyId": 1,
9 "salesChannelId": 1,
10 "operation": "create",
11 "url": "https://validator.exemplo.com/customers/validate",
12 "errorType": "business",
13 "httpStatus": 422,
14 "requestTimeMs": 241,
15 "request": {
16 "operation": "create",
17 "domain": "loja.exemplo.com.br",
18 "customer": {
19 "id": null,
20 "email": "cl<em></em>*@exemplo.com",
21 "nameCorporateName": "J<strong><em> S</strong></em>",
22 "phone": "+55<strong></strong><strong></strong>78",
23 "documents": [
24 {
25 "type": "cpf",
26 "document": "<strong><em>.</strong></em>.<strong>*-</strong>"
27 }
28 ]
29 }
30 },
31 "response": {
32 "status": "error",
33 "message": "Cadastro reprovado por política antifraude."
34 },
35 "createdAt": "2026-04-15 16:04:30"
36 }
37 ],
38 "pagination": {
39 "limit": 20,
40 "offset": 0,
41 "pages": 1,
42 "registers": 1
43 }
44 }
45}

⚠️ Possíveis erros:

Código InternoCódigo HTTPDescrição
Sem código interno específico401Token ausente, inválido ou expirado
Sem código interno específico403Usuário autenticado sem escopo CUSTOMER_READ

Uappi é a melhor opção para o crescimento da sua loja!

;