Gerenciamento de Clientes (Admin)
Visão Geral
Este módulo permite que usuários administrativos gerenciem os clientes cadastrados na loja 👥.
Diferente das rotas destinadas ao cliente autenticado, estas rotas pertencem ao painel administrativo e possibilitam operações completas de CRUD sobre os clientes.
Permissão
Todas as rotas exigem autenticação via middleware UserAuth, além da validação de escopos de permissão adequados.
- CUSTOMER_READ: necessário para listagem e consulta de clientes
- CUSTOMER_WRITE: necessário para criação, atualização e remoção de clientes
Notas e Considerações
É importante destacar que, no contexto Uappi, o termo Cliente refere-se ao cliente final da loja.
Portanto, sempre que mencionado “Cliente” neste módulo, está se tratando do consumidor final, e não de um usuário administrativo.
Listagem de Clientes
/customers
Endpoint responsável por listar os clientes cadastrados na loja
Descrição
Retorna uma lista paginada de todos os clientes cadastrados na loja.
Este endpoint é destinado ao painel administrativo e requer autenticação de usuário com permissão de leitura de clientes.
Parâmetros de Query
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Authorization | Bearer {token} | Token de autenticação |
Campos Disponíveis (fields)
| Campo | Descrição |
|---|---|
| addresses | Lista de endereços |
| documents | Documentos cadastrados |
| flags | Preferências de notificação |
| totalOrderQuantity | Quantidade de pedidos |
| cancelledOrderQuantity | Quantidade de pedidos cancelados |
| totalOrderValue | Valor total de pedidos |
| lastOrder | Dados do último pedido |
| pointSystemAmount | Saldo de pontos |
| additionalFields | Campos adicionais preenchidos pelo cliente |
Campos de Condição Disponíveis
| Campo | Tipo | Descrição |
|---|---|---|
| id | integer | Filtrar por ID do cliente |
| string | Filtrar por email | |
| nameCorporateName | string | Buscar por nome do cliente |
| isCorporate | boolean | Filtrar por tipo (pessoa física/jurídica) |
| active | boolean | Filtrar por status |
| salesChannelId | integer | Filtrar por canal de vendas |
| additionalField | string ou array | Filtrar por campo adicional no cliente. Para entender como esse filtro funciona, consulte o tópico Filtrando campos adicionais em listagens |
Campos de Ordenação Disponíveis
| Campo | Descrição |
|---|---|
| id | Ordenar lista por ID do cliente |
| Ordenar lista por email | |
| nameCorporateName | Ordenar lista por nome |
| createdAt | Ordenar lista por data de criação |
Exemplo de Requisição
1curl --request GET \2 --url '{{MAIN_URL}}/customers?limit=10&offset=0' \3 --header 'Authorization: Bearer SEU_TOKEN_AQUI'Exemplo com Filtros
1curl --request GET \2 --url '{{MAIN_URL}}/customers?limit=10&offset=0&condition[active]=true&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": 1,7 "salesChannelId": 1,8 "tradePolicyId": 1,9 "email": "joao@uappi.com.br",10 "dealerGroupId": 0,11 "nameCorporateName": "João Gomes",12 "tradeName": "",13 "isCorporate": false,14 "gender": "undefined",15 "nationality": "BRA",16 "birthdate": "2000-01-01",17 "phone": "+5518912345678",18 "walletAmount": 0,19 "pointSystemAmount": 0,20 "orderQuantity": 0,21 "cancelledOrderQuantity": 0,22 "orderValue": 0,23 "lastOrder": null,24 "origin": "frontend",25 "createdAt": "2026-01-01 01:01:59",26 "active": true,27 "deleted": false,28 "masked": false,29 "addresses": [],30 "documents": [31 {32 "type": "cpf",33 "document": "12345678901"34 }35 ],36 "flags": null,37 "additionalFields": null38 }39 ],40 "pagination": {41 "limit": 10,42 "offset": 0,43 "pages": 5,44 "registers": 4845 }46 }47}⚠️ Possíveis erros:
Atenção: a seguir estão destacados os principais erros que podem ocorrer neste endpoint.
Os cenários descritos representam os erros mais relevantes do contexto atual, servindo como referência para entendimento e tratamento das falhas.
| Código Interno | Código HTTP | Descrição |
|---|---|---|
| USER_PROFILE_TRADE_POLICY_MISCONFIGURED | 422 | O perfil do usuário possui restrição de política comercial ativa, mas nenhuma política comercial permitida está configurada. |
Detalhe de Cliente
/customers/{customerId}
Endpoint responsável por retornar os detalhes de um cliente específico
Descrição
Retorna os dados completos de um cliente específico, incluindo endereços, documentos, preferências e histórico de pedidos. Este endpoint é destinado ao painel administrativo.
Parâmetros de Query
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Authorization | Bearer {token} | Token de autenticação |
Parâmetros de URL
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| customerId | integer | Sim | ID do cliente |
Campos Disponíveis (fields)
| Campo | Descrição |
|---|---|
| addresses | Lista de endereços |
| documents | Documentos cadastrados |
| flags | Preferências de notificação |
| totalOrderQuantity | Quantidade de pedidos |
| cancelledOrderQuantity | Quantidade de pedidos cancelados |
| totalOrderValue | Valor total de pedidos |
| lastOrder | Dados do último pedido |
| pointSystemAmount | Saldo de pontos |
| additionalFields | Campos adicionais preenchidos pelo cliente |
Exemplo de Requisição
1curl --request GET \2 --url '{{MAIN_URL}}/customers/1' \3 --header 'Authorization: Bearer SEU_TOKEN_AQUI'Exemplo com Campos Específicos
1curl --request GET \2 --url '{{MAIN_URL}}/customers/1?fields[]=addresses&fields[]=documents&fields[]=flags&fields[]=additionalFields' \3 --header 'Authorization: Bearer SEU_TOKEN_AQUI'✅ Resposta de Sucesso
HTTP Status: 200 OK
1{2 "id": 123,3 "salesChannelId": 1,4 "tradePolicyId": 1,5 "email": "joao.silva@email.com",6 "dealerGroupId": null,7 "nameCorporateName": "Joao Silva",8 "tradeName": "Silva",9 "isCorporate": false,10 "gender": "male",11 "nationality": "BRA",12 "birthdate": "1990-01-01",13 "phone": "+5518912345678",14 "walletAmount": 0,15 "pointSystemAmount": 0,16 "orderQuantity": 0,17 "cancelledOrderQuantity": 0,18 "orderValue": 0,19 "lastOrder": {20 "id": 1,21 "cartId": "CART-2025-123",22 "tradePolicyId": 1,23 "userId": null,24 "userEmail": null,25 "userName": null,26 "code": "ORD-2025-123",27 "salesChannelDomain": "loja.com.br",28 "currency": "BRL",29 "createdAt": "2025-01-01 01:01:59",30 "issuedAt": "2025-01-01 01:00:59",31 "masked": false,32 "payments": [],33 "customer": null,34 "addresses": null,35 "values": {36 "orderId": 1,37 "subtotalValue": 299.90,38 "additionValue": 0,39 "shippingValue": 0,40 "discountValue": 0,41 "totalValue": 299.9042 },43 "observations": null44 },45 "origin": "web",46 "createdAt": "2025-01-01 10:00:00",47 "active": true,48 "deleted": false,49 "masked": false,50 "addresses": [51 {52 "id": 1,53 "main": true,54 "zipCode": "12345-000",55 "identification": "Casa",56 "street": "Avenida Paulista",57 "number": "123",58 "city": "São Paulo",59 "complement": "Apto 101",60 "district": "Bela Vista",61 "state": "São Paulo",62 "recipient": "João Silva",63 "stateCode": "SP",64 "countryCode": "BR",65 "createdAt": "2025-01-01 01:01:59",66 "updatedAt": "2025-01-01 01:01:59"67 }68 ],69 "documents": [70 {71 "type": "cpf",72 "document": "12345678900"73 }74 ],75 "flags": {76 "sendPromotionalEmail": true,77 "sendPromotionalSms": false,78 "sendOrderEmail": true,79 "sendOrderSms": true80 },81 "additionalFields": [82 {83 "name": "Tem intolerância a lactose?",84 "code": "tem-intolerancia-a-lactose",85 "type": "boolean",86 "value": false87 },88 {89 "name": "Nome da mãe",90 "code": "nome-da-mae",91 "type": "text",92 "value": "Fulana de Tal"93 },94 {95 "name": "Quantidade filhos",96 "code": "quantidade-filhos",97 "type": "numeric",98 "value": 299 }100 ]101}⚠️ Possíveis erros:
Atenção: a seguir estão destacados os principais erros que podem ocorrer neste endpoint.
Os cenários descritos representam os erros mais relevantes do contexto atual, servindo como referência para entendimento e tratamento das falhas.
| Código Interno | Código HTTP | Descrição |
|---|---|---|
| UAPPI_STORE_CUSTOMER_NOT_FOUND | 404 | Cliente solicitado não foi encontrado |
| USER_PROFILE_TRADE_POLICY_MISCONFIGURED | 422 | O perfil do usuário possui restrição de política comercial ativa, mas nenhuma política comercial permitida está configurada. |
Cadastro de Cliente
/customers
Endpoint responsável por cadastrar um novo cliente na loja
Descrição
Permite aos usuários administrativos cadastrar um novo cliente na loja, incluindo dados pessoais, documentos e configurações iniciais.
Este endpoint é destinado ao painel administrativo e requer permissão de escrita de clientes.
⚠️ Observações: Mesmo que existam campos adicionais obrigatórios a obrigatoriedade deles não será validada (apenas seus valores e tipagens), evitando quebras indesejadas no fluxo de cadastro.
- A regra de idade mínima é aplicada conforme a configuração
customers/validation/minimum-age. Valor0desativa a validação. - A validação do domínio do e-mail é aplicada quando a configuração
customers/validation/email-domainestá ativa. O cadastro é bloqueado quando o domínio do e-mail não possui registros MX válidos. - A validação externa de cadastro é executada quando a configuração
customers/validation/external-urlestá preenchida com URL válida.
Parâmetros de query
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Content-Type | application/json | Tipo de conteúdo |
Authorization | Bearer {token} | Token de autenticação do usuário |
Parâmetros do Corpo
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| string | Sim | Email do cliente (max 255 caracteres) | |
| nameCorporateName | string | Sim | Nome completo (pessoa física) ou razão social (pessoa jurídica) |
| isCorporate | boolean | Sim | Define se é pessoa jurídica (true) ou física (false) |
| gender | string | Sim | Gênero: male, female ou undefined |
| nationality | string | Sim | Código do país em formato alpha-3 (ex: BRA, USA) |
| phone | string | Sim | Telefone/celular no formato internacional |
| origin | string | Sim | Origem do cadastro: frontend, api ou admin |
| birthdate | string | Sim | Data de nascimento no formato YYYY-MM-DD |
| password | string | Não | Senha (8-64 caracteres) |
| tradeName | string | Condicional | Nome fantasia (obrigatório se isCorporate = true) |
| documents | array | Sim | Array com documentos do cliente |
| documents.*.type | string | Sim | Tipo: cpf, cnpj, ie, rg, document1, document2, document3 |
| documents.*.document | string | Sim | Número do documento (max 100 caracteres) |
| additionalFields | array ou null | Não | Campos adicionais do cliente. |
| additionalFields.*.code | string | Sim | Código do campo adicional. |
| additionalFields.*.value | string, boolean, integer, float, array | Sim | Valor do campo adicional. |
| sendNotification | boolean | Não | Determina se o e-mail de recuperação de senha será enviado, caso não seja informado valor padrão é false. |
Exemplo de Requisição - Pessoa Física
1curl --request POST \2 --url '{{MAIN_URL}}/customers' \3 --header 'Authorization: Bearer SEU_TOKEN_AQUI' \4 --header 'Content-Type: application/json' \5 --data '{6 "email": "joao.silva@exemplo.com",7 "nameCorporateName": "Joao Silva",8 "isCorporate": false,9 "gender": "male",10 "nationality": "BRA",11 "birthdate": "1990-05-15",12 "phone": "+5511912345678",13 "origin": "admin",14 "password": "senhaSegura123",15 "documents": [16 {17 "type": "cpf",18 "document": "12345678900"19 }20 ],21 "additionalFields": [22 {23 "code": "quantidade-filhos",24 "value": 225 },26 {27 "code": "tem-intolerancia-a-lactose",28 "value": "Valor inválido"29 },30 {31 "code": "interesses-de-compra",32 "value": ["Moda", "Tecnologia"]33 }34 ],35 "sendNotification": false36 }'Exemplo de Requisição - Pessoa Jurídica
1curl --request POST \2 --url '{{MAIN_URL}}/customers' \3 --header 'Authorization: Bearer SEU_TOKEN_AQUI' \4 --header 'Content-Type: application/json' \5 --data '{6 "email": "empresa@exemplo.com",7 "nameCorporateName": "Empresa XYZ Ltda",8 "tradeName": "XYZ",9 "isCorporate": true,10 "gender": "undefined",11 "nationality": "BRA",12 "birthdate": "2010-01-01",13 "phone": "+5511912345678",14 "origin": "admin",15 "password": "senhaSegura123",16 "documents": [17 {18 "type": "cnpj",19 "document": "12345678000199"20 },21 {22 "type": "ie",23 "document": "123456789"24 }25 ],26 "additionalFields": [27 {28 "code": "quantidade-filhos",29 "value": 230 },31 {32 "code": "tem-intolerancia-a-lactose",33 "value": "Valor inválido"34 },35 {36 "code": "interesses-de-compra",37 "value": ["Moda", "Tecnologia"]38 }39 ]40 }'✅ Resposta de Sucesso
HTTP Status: 200 OK
1{2 "id": 1,3 "salesChannelId": 1,4 "tradePolicyId": 1,5 "email": "joao.silva@exemplo.com",6 "dealerGroupId": null,7 "nameCorporateName": "Joao Silva",8 "tradeName": "",9 "isCorporate": false,10 "gender": "male",11 "nationality": "BRA",12 "birthdate": "1990-05-15",13 "phone": "+5511999887766",14 "walletAmount": 0,15 "pointSystemAmount": 0,16 "orderQuantity": 0,17 "cancelledOrderQuantity": 0,18 "orderValue": 0,19 "lastOrder": null,20 "origin": "admin",21 "createdAt": "2026-01-01 01:01:59",22 "active": true,23 "deleted": false,24 "masked": false,25 "addresses": null,26 "documents": [27 {28 "type": "cpf",29 "document": "12345678900"30 }31 ],32 "flags": null,33 "additionalFields": null34}⚠️ Possíveis Erros:
Atenção: a seguir estão destacados os principais erros que podem ocorrer neste endpoint.
Os cenários descritos representam os erros mais relevantes do contexto atual, servindo como referência para entendimento e tratamento das falhas.
| Código Interno | Código HTTP | Descrição |
|---|---|---|
| UAPPI_STORE_CUSTOMER_EMAIL_ALREADY_IN_USE | 409 | O e-mail solicitado já está sendo utilizado por outro cliente |
| UAPPI_STORE_ALREADY_USED_CUSTOMER_DOCUMENT | 409 | O documento solicitado já está em uso |
| UAPPI_CORE_INVALID_DOCUMENT_TYPE | 400 | O tipo de documento solicitado não foi encontrado |
| UAPPI_CORE_EMPTY_DOCUMENT | 400 | O documento não pode estar vazio |
| UAPPI_CORE_INVALID_CPF | 400 | O CPF é inválido |
| UAPPI_CORE_INVALID_CNPJ | 400 | O CNPJ é inválido |
| UAPPI_STORE_INVALID_PASSWORD_LENGTH | 400 | Tamanho da senha informada é inválido |
| UAPPI_STORE_CUSTOMER_MINIMUM_AGE_NOT_REACHED | 400 | Cliente não atende a idade mínima configurada para cadastro |
| UAPPI_STORE_CUSTOMER_INVALID_EMAIL_DOMAIN | 400 | O domínio do e-mail informado não possui registros para receber e-mails |
| UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_REJECTED | 422 | Serviço externo rejeitou o cadastro com regra de negócio |
| UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_INVALID_CONTRACT | 502 | Serviço externo respondeu com contrato inválido para validação |
| UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_UNAVAILABLE | 502 | Serviço externo de validação está indisponível |
| UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_TIMEOUT | 504 | Serviço externo de validação excedeu o tempo limite |
| UAPPI_CORE_COMMON_ADDITIONAL_FIELD_INVALID_VALUE_TYPE | 400 | O tipo do valor informado não é aceitável para o tipo do campo. Em caso de campos do tipo "upload" indica que o formato do arquivo enviado é inválido. |
| UAPPI_CORE_COMMON_ADDITIONAL_FIELD_FILE_TOO_LARGE | 400 | O tamanho do arquivo enviado é maior que 2048 kilobytes. |
| UAPPI_CORE_COMMON_ADDITIONAL_FIELD_INVALID_OPTION | 400 | A opção escolhida como valor do campo não é aceitável entre as opções configuradas. |
Atualização de Cliente
/customers/{customerId}
Endpoint responsável por atualizar os dados de um cliente
Descrição
Endpoint que permite aos usuários administrativos atualizar os dados de um cliente existente 👤.
Destinado ao painel administrativo, este endpoint possibilita a alteração de campos que não podem ser modificados pelo próprio cliente, como, por exemplo, o status de ativação.
Dessa forma, garante maior controle operacional e administrativo sobre o cadastro do cliente na loja.
A atualização também executa validação externa quando a configuração customers/validation/external-url está preenchida com URL válida.
Parâmetros de Query
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Content-Type | application/json | Tipo de conteúdo |
Authorization | Bearer {token} | Token de autenticação |
Parâmetros de URL
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| customerId | integer | Sim | ID do cliente |
Parâmetros do Corpo
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| string | Sim | Email válido (máximo 255 caracteres) | |
| nameCorporateName | string | Sim | Nome ou razão social (máximo 255 caracteres) |
| tradeName | string | Sim | Sobrenome ou nome fantasia (máximo 255 caracteres) |
| isCorporate | boolean | Sim | Se é pessoa jurídica |
| active | boolean | Sim | Status de ativação do cliente |
| gender | string | Sim | Gênero (male, female, undefined) |
| phone | string | Sim | Telefone no formato internacional (+5511987654321) |
Exemplo de Requisição
1curl --request PUT \2 --url '{{MAIN_URL}}/customers/1' \3 --header 'Authorization: Bearer SEU_TOKEN_AQUI' \4 --header 'Content-Type: application/json' \5 --data '{6 "email": "joao.silva.novo@email.com",7 "nameCorporateName": "Joao Silva Santos",8 "tradeName": "Santos",9 "isCorporate": false,10 "active": true,11 "gender": "male",12 "phone": "+5511987654321"13 }'Exemplo - Inativando um Cliente
1curl --request PUT \2 --url '{{MAIN_URL}}/customers/1' \3 --header 'Authorization: Bearer SEU_TOKEN_AQUI' \4 --header 'Content-Type: application/json' \5 --data '{6 "email": "joao.silva@email.com",7 "nameCorporateName": "Joao Silva",8 "tradeName": "Silva",9 "isCorporate": false,10 "active": false,11 "gender": "male",12 "phone": "+5511987654321"13 }'✅ Resposta de Sucesso
HTTP Status: 200 OK
1{2 "id": 1,3 "salesChannelId": 1,4 "tradePolicyId": 1,5 "email": "joao.silva.novo@email.com",6 "dealerGroupId": null,7 "nameCorporateName": "Joao Silva Santos",8 "tradeName": "Santos",9 "isCorporate": false,10 "gender": "male",11 "nationality": "BRA",12 "birthdate": "1990-01-01",13 "phone": "+5511987654321",14 "walletAmount": 150.00,15 "pointSystemAmount": 500,16 "orderQuantity": 5,17 "cancelledOrderQuantity": 0,18 "orderValue": 2500.00,19 "lastOrder": null,20 "origin": "web",21 "createdAt": "2024-01-01 10:00:00",22 "active": true,23 "deleted": false,24 "masked": false,25 "addresses": [],26 "documents": [],27 "flags": null28}⚠️ Possíveis erros:
Atenção: a seguir estão destacados os principais erros que podem ocorrer neste endpoint.
Os cenários descritos representam os erros mais relevantes do contexto atual, servindo como referência para entendimento e tratamento das falhas.
| Código Interno | Código HTTP | Descrição |
|---|---|---|
| UAPPI_STORE_CUSTOMER_NOT_FOUND | 404 | Cliente solicitado não foi encontrado |
| UAPPI_STORE_CUSTOMER_EMAIL_ALREADY_IN_USE | 409 | O e-mail solicitado já está sendo utilizado por outro cliente |
| UAPPI_STORE_CUSTOMER_INVALID_EMAIL_DOMAIN | 400 | O domínio do e-mail informado não possui registros para receber e-mails |
| UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_REJECTED | 422 | Serviço externo rejeitou a atualização com regra de negócio |
| UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_INVALID_CONTRACT | 502 | Serviço externo respondeu com contrato inválido para validação |
| UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_UNAVAILABLE | 502 | Serviço externo de validação está indisponível |
| UAPPI_STORE_CUSTOMER_EXTERNAL_VALIDATION_TIMEOUT | 504 | Serviço externo de validação excedeu o tempo limite |
Remoção de Cliente
/customers/{customerId}
Endpoint responsável por remover um cliente da loja
Descrição
Este endpoint permite aos usuários administrativos remover um cliente da loja.
A remoção é parcial: o cliente é inativado e seus dados são anonimizados para manter a conformidade com a LGPD, preservando o histórico de pedidos.
Ao remover um cliente:
- Inativação: O cliente é marcado como inativo (
active: false) - Procedimento de Delete: O cliente é marcado como deletado (
deleted: true) - Anonimização: Dados pessoais são mascarados para conformidade com LGPD
- Histórico: O histórico de pedidos é preservado, mas com dados anonimizados
Parâmetros de Query
Headers Obrigatórios
| Header | Valor | Descrição |
|---|---|---|
Content-Type | application/json | Tipo de conteúdo |
Authorization | Bearer {userToken} | Token de autenticação do usuário |
Parâmetros de URL
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| customerId | integer | Sim | ID do cliente |
Parâmetros do Corpo
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| requestedAt | string | Sim | Data da solicitação de remoção (formato: YYYY-MM-DD) |
Exemplo de Requisição
1curl --request DELETE \2 --url '{{MAIN_URL}}/customers/123' \3 --header 'Authorization: Bearer SEU_TOKEN_AQUI' \4 --header 'Content-Type: application/json' \5 --data '{6 "requestedAt": "2026-01-01"7 }'✅ Resposta de Sucesso
HTTP Status: 200 OK
1{2 "status": true,3 "data": true4}⚠️ Possíveis erros:
Atenção: a seguir estão destacados os principais erros que podem ocorrer neste endpoint.
Os cenários descritos representam os erros mais relevantes do contexto atual, servindo como referência para entendimento e tratamento das falhas.
| Código Interno | Código HTTP | Descrição |
|---|---|---|
| UAPPI_STORE_CUSTOMER_NOT_FOUND | 404 | Cliente solicitado não foi encontrado |