# API Backend — portal-modumfiscal-web Documentação dos endpoints que o portal consome. Base URL: `https://sistema.modumfiscal.com.br/api/v1`. **Envelope padrão de resposta (sucesso):** ```json { "timestamp": "2025-05-18T10:00:00Z", "statusCode": 200, "responseType": "SUCCESS", "message": "OK", "data": { } } ``` **Envelope de erro:** ```json { "statusCode": 422, "message": "Unprocessable Entity", "internalCode": "119", "description": "Registro não foi encontrado." } ``` Respostas binárias (PDF) retornam `Content-Type: application/pdf` direto — sem envelope. --- ## Módulo Público — sem autenticação Headers obrigatórios em toda requisição: - `X-Municipio: ` - `X-Dominio: ` --- ### Prefeitura (bootstrap) #### `GET /publico/prefeitura/{dominio}` Retorna a configuração visual e institucional da prefeitura. **Response `data`:** ```json { "idMunicipio": 1, "nomePrefeitura": "Prefeitura Municipal de Tutóia", "nomeMunicipio": "Tutóia", "uf": "MA", "template": "tutoia", "pathLogo": "/logos/tutoia.png", "pathBackground": "/backgrounds/tutoia.jpeg", "corPrimaria": "#F59E0B", "cnpj": "12.345.678/0001-90", "site": "https://tutoia.ma.gov.br", "email": "atendimento@tutoia.ma.gov.br", "telefone": "(98) 3478-1234" } ``` > `pathLogo` e `pathBackground` são paths relativos — o frontend resolve para URL absoluta via `resolverUrl()`. --- ### Certidão Pública #### `GET /publico/certidao/consultar` Consulta a situação fiscal do contribuinte. **Query params:** | Param | Tipo | Obrigatório | Descrição | |---|---|---|---| | `documento` | string | sim | CPF (11 dígitos) ou CNPJ (14 dígitos) sem formatação | **Response `data`:** ```json { "situacao": "NEGATIVA", "nomeContribuinte": "João da Silva Santos" } ``` `situacao` possíveis: `NEGATIVA` · `POSITIVA` · `POSITIVA_EFEITOS_NEGATIVA` --- #### `GET /publico/certidao/emitir` Emite a certidão em PDF. **Query params:** | Param | Tipo | Obrigatório | Descrição | |---|---|---|---| | `documento` | string | sim | CPF/CNPJ sem formatação | | `tipoCertidao` | string | sim | `NEGATIVA` · `POSITIVA` · `POSITIVA_EFEITOS_NEGATIVA` | **Response:** `application/pdf` (binário direto, sem envelope) --- ### IPTU Público #### `GET /publico/iptu/consultar` Retorna todos os imóveis e débitos de IPTU do contribuinte ou de uma inscrição específica. **Query params:** | Param | Tipo | Obrigatório | Descrição | |---|---|---|---| | `documento` | string | condicional | CPF/CNPJ sem formatação (informar `documento` **ou** `inscricao`) | | `inscricao` | string | condicional | Inscrição imobiliária (ex: `0001.001.0001.001`) | **Response `data`:** ```json { "content": [ { "inscricaoImobiliaria": "0001.001.0001.001", "enderecoCompleto": "Rua das Flores, 100 — Centro", "debitos": [ { "id": "d1", "descricao": "IPTU 2025 — Cota 4/10", "vencimento": "30/04/2025", "valor": 125.90, "valorAtualizado": 138.49, "status": "VENCIDO" } ] } ] } ``` `status` possíveis: `VENCIDO` · `A_VENCER` · `PAGO` · `PARCELADO` --- #### `GET /publico/iptu/carne` Emite o carnê completo de IPTU em PDF. **Query params:** | Param | Tipo | Obrigatório | Descrição | |---|---|---|---| | `inscricao` | string | sim | Inscrição imobiliária | **Response:** `application/pdf` --- #### `GET /publico/iptu/boleto` Emite o boleto avulso de uma parcela. **Query params:** | Param | Tipo | Obrigatório | Descrição | |---|---|---|---| | `idDebito` | string | sim | ID do débito retornado por `/consultar` | **Response:** `application/pdf` --- ### Primeiro Acesso Fluxo de 4 etapas para o contribuinte criar senha de acesso ao portal. #### `GET /publico/primeiro-acesso/verificar` Valida se o documento tem cadastro e retorna os canais disponíveis para envio do código. **Query params:** | Param | Tipo | Obrigatório | |---|---|---| | `documento` | string | sim | **Response `data`:** ```json { "nome": "Maria Aparecida Santos", "canais": [ { "tipo": "EMAIL", "valor": "ma***@gmail.com" }, { "tipo": "WHATSAPP", "valor": "(98) *****-8901" }, { "tipo": "SMS", "valor": "(98) *****-8901" } ] } ``` `tipo` possíveis: `EMAIL` · `WHATSAPP` · `SMS` --- #### `POST /publico/primeiro-acesso/codigo` Envia o código de 6 dígitos para o canal escolhido. **Request body:** ```json { "documento": "12345678900", "canal": "EMAIL" } ``` **Response `data`:** ```json { "enviado": true } ``` --- #### `POST /publico/primeiro-acesso/validar` Valida o código digitado e retorna um token temporário para definição de senha. **Request body:** ```json { "documento": "12345678900", "codigo": "123456" } ``` **Response `data`:** ```json { "token": "eyJhb..." } ``` Erros: `422` se código inválido ou expirado. --- #### `POST /publico/primeiro-acesso/senha` Define a nova senha usando o token temporário. **Request body:** ```json { "token": "eyJhb...", "senha": "MinhaS3nha!" } ``` **Response `data`:** ```json { "sucesso": true } ``` --- ### Credenciamento Fluxo para novo contribuinte solicitar cadastro no sistema. #### `GET /publico/credenciamento/verificar` Verifica se o documento já tem cadastro ou pode ser credenciado. **Query params:** | Param | Tipo | Obrigatório | |---|---|---| | `documento` | string | sim | **Response `data`:** ```json { "situacao": "APTO" } ``` `situacao` possíveis: - `APTO` — pode prosseguir com o credenciamento - `JA_CREDENCIADO` — já tem acesso ao sistema - `BLOQUEADO` — documento bloqueado (contatar prefeitura) --- #### `GET /publico/cep/{cep}` Busca endereço por CEP para auto-preenchimento no formulário de credenciamento. **Path param:** `cep` — 8 dígitos sem hífen **Response `data`:** ```json { "logradouro": "Rua das Acácias", "bairro": "Centro", "localidade": "Tutóia", "uf": "MA" } ``` --- #### `POST /publico/credenciamento/solicitar` Envia a solicitação de credenciamento para análise da prefeitura. **Request body (Pessoa Física):** ```json { "documento": "12345678900", "tipoPessoa": "FISICA", "nomeCompleto": "João da Silva Santos", "dataNascimento": "1990-05-15", "email": "joao@email.com", "emailConfirmacao": "joao@email.com", "telefone": "98991234567", "whatsapp": true, "endereco": { "cep": "65900000", "logradouro": "Rua das Flores", "numero": "100", "complemento": "Apto 201", "bairro": "Centro", "cidade": "Tutóia", "uf": "MA" } } ``` **Request body adicional (Pessoa Jurídica):** ```json { "tipoPessoa": "JURIDICA", "razaoSocial": "Empresa LTDA", "nomeFantasia": "Empresa", "inscricaoEstadual": "12345678", "representanteLegal": { "nomeCompleto": "João da Silva", "cpf": "12345678900", "cargo": "Diretor" } } ``` **Response `data`:** ```json { "protocolo": "CRED-2025-00123" } ``` --- ## Módulo Portal — requer autenticação Header obrigatório além dos de tenant: - `Authorization: Bearer ` --- ### Painel #### `GET /contribuinte/painel/resumo` Dados do card de resumo do dashboard. **Response `data`:** ```json { "totalDebitos": 1250.90, "certidoesAtivas": 2, "alvarasAndamento": 2, "ultimoPagamento": 430.00, "debitosVencidos": 1 } ``` --- #### `GET /contribuinte/painel/atividades` Lista das últimas atividades do contribuinte. **Response `data`:** ```json { "content": [ { "tipo": "PAGAMENTO", "descricao": "IPTU 2025 — Parcela 3/10 paga", "data": "15/05/2025" }, { "tipo": "CERTIDAO", "descricao": "Certidão Negativa emitida", "data": "10/05/2025" } ] } ``` `tipo` possíveis: `PAGAMENTO` · `CERTIDAO` · `DEBITO` · `ALVARA` · `CADASTRO` --- ### Débitos #### `GET /contribuinte/debitos` Lista os débitos do contribuinte com filtros opcionais. **Query params:** | Param | Tipo | Obrigatório | Descrição | |---|---|---|---| | `tipo` | string | não | `IPTU` · `ISS` · `TAXA` · `MULTA` | | `status` | string | não | `VENCIDO` · `A_VENCER` · `PARCELADO` | **Response `data`:** ```json { "content": [ { "id": "deb1", "descricao": "IPTU 2025 — Cota 4/10", "tipo": "IPTU", "referencia": "ABR/2025", "vencimento": "30/04/2025", "valor": 125.90, "valorAtualizado": 138.49, "status": "VENCIDO" } ] } ``` `valorAtualizado` inclui juros e multa (pode ser igual a `valor` se em dia). --- #### `GET /contribuinte/debitos/{id}/guia` Emite a guia de pagamento (boleto/DAM) de um débito específico em PDF. **Path param:** `id` — ID do débito **Response:** `application/pdf` --- ### Certidões #### `GET /contribuinte/certidoes` Lista todas as certidões emitidas pelo contribuinte. **Response `data`:** ```json { "content": [ { "id": "cert1", "tipo": "Certidão Negativa de Débitos", "numero": "CN-2025-00481", "dataEmissao": "10/05/2025", "dataValidade": "07/11/2025", "status": "ATIVA" } ] } ``` `status` possíveis: `ATIVA` · `VENCIDA` · `CANCELADA` --- #### `GET /contribuinte/certidoes/{id}/pdf` Reemite uma certidão em PDF. **Path param:** `id` — ID da certidão **Response:** `application/pdf` > Retorna `422` se a certidão estiver com status `CANCELADA`. --- ### Alvarás #### `GET /contribuinte/alvaras` Lista os processos de alvará do contribuinte. **Query params:** | Param | Tipo | Obrigatório | Descrição | |---|---|---|---| | `status` | string | não | Filtro por status do processo | **Response `data`:** ```json { "content": [ { "id": "alv1", "tipo": "Alvará de Funcionamento — Comércio Varejista", "numeroProcesso": "ALV-2025-00342", "status": "EM_ANALISE", "ultimaAtualizacao": "14/05/2025", "etapas": [ { "nome": "Protocolo", "concluida": true, "atual": false }, { "nome": "Análise", "concluida": false, "atual": true }, { "nome": "Vistoria", "concluida": false, "atual": false }, { "nome": "Emissão", "concluida": false, "atual": false } ] } ] } ``` `status` possíveis: `EM_ANALISE` · `AGUARDANDO_DOCUMENTOS` · `DEFERIDO` · `INDEFERIDO` · `CANCELADO` --- ### Pagamentos #### `GET /contribuinte/pagamentos` Histórico de pagamentos do contribuinte, filtrável por ano. **Query params:** | Param | Tipo | Obrigatório | Descrição | |---|---|---|---| | `ano` | integer | não | Ano de referência (padrão: ano atual) | **Response `data`:** ```json { "content": [ { "id": "pag1", "descricao": "IPTU 2025 — Cota 3/10", "referencia": "MAR/2025", "dataPagamento": "28/03/2025", "formaPagamento": "PIX", "valor": 125.90 } ] } ``` `formaPagamento` possíveis: `BOLETO` · `PIX` · `CARTAO` · `TRANSFERENCIA` · `ESPECIE` --- #### `GET /contribuinte/pagamentos/{id}/comprovante` Baixa o comprovante de um pagamento em PDF. **Path param:** `id` — ID do pagamento **Response:** `application/pdf` --- ### Dados Cadastrais #### `GET /contribuinte/dados` Retorna os dados cadastrais completos do contribuinte autenticado. **Response `data` (Pessoa Física):** ```json { "tipoPessoa": "FISICA", "documento": "123.456.789-00", "nomeCompleto": "João da Silva Santos", "dataNascimento": "15/06/1975", "email": "joao.santos@email.com", "telefone": "(98) 99123-4567", "whatsapp": true, "endereco": { "cep": "65900-000", "logradouro": "Rua das Flores", "numero": "100", "complemento": "Apto 201", "bairro": "Centro", "cidade": "Tutóia", "uf": "MA" } } ``` **Campos adicionais (Pessoa Jurídica):** ```json { "tipoPessoa": "JURIDICA", "documento": "12.345.678/0001-90", "razaoSocial": "Empresa LTDA", "nomeFantasia": "Empresa", "inscricaoEstadual": "12345678" } ``` --- #### `PUT /contribuinte/dados/contato` Atualiza os dados de contato editáveis (email, telefone, WhatsApp). **Request body:** ```json { "email": "novo@email.com", "telefone": "98991234567", "whatsapp": true } ``` `telefone` deve ser enviado **sem formatação** (apenas dígitos). **Response `data`:** ```json { "atualizado": true } ``` --- ## Avisos (pendente no backend) #### `GET /publico/avisos/{dominio}` Retorna os avisos/banners exibidos no carousel da Home. > **Status:** endpoint ainda não implementado no backend. O frontend usa dados estáticos hardcoded em `HomeView.vue`. **Response `data` esperada:** ```json { "content": [ { "id": "av1", "titulo": "IPTU 2025 — Prazo final", "descricao": "Últimas parcelas com desconto até 30 de junho.", "tipo": "ALERTA", "ativo": true } ] } ``` `tipo` sugeridos: `INFO` · `ALERTA` · `URGENTE` --- ## Fluxo de Autenticação O portal usa **Keycloak PKCE** — nenhuma credencial trafega pelo frontend. ``` 1. Usuário informa CPF/CNPJ na Home 2. LoginView monta — exibe doc mascarado + campo senha 3. entrar() → redireciona para Keycloak (PKCE code challenge) 4. Keycloak autentica e redireciona de volta com ?code= 5. authService troca code por access_token + refresh_token 6. authStore.setSession(token, userInfo) persiste sessão 7. router.push({ name: 'painel' }) ``` **Realm:** `modumfiscal-dev` **Client ID:** `portal-modumfiscal-web` **Grant type:** `authorization_code` com PKCE (S256) **Token endpoint:** `https://keycloakprod.modumfiscal.com.br/realms/modumfiscal-dev/protocol/openid-connect/token` O `preferred_username` do JWT é o CPF/CNPJ sem formatação — usado como identificador do contribuinte nas chamadas ao backend. --- ## Status de Implementação dos Endpoints | Endpoint | Frontend pronto | Backend pronto | Mock | |---|---|---|---| | `GET /publico/prefeitura/{dominio}` | ✓ | ✓ | — | | `GET /publico/certidao/consultar` | ✓ | pendente | ✓ | | `GET /publico/certidao/emitir` | ✓ | pendente | ✓ | | `GET /publico/iptu/consultar` | ✓ | pendente | ✓ | | `GET /publico/iptu/carne` | ✓ | pendente | ✓ | | `GET /publico/iptu/boleto` | ✓ | pendente | ✓ | | `GET /publico/primeiro-acesso/verificar` | ✓ | pendente | ✓ | | `POST /publico/primeiro-acesso/codigo` | ✓ | pendente | ✓ | | `POST /publico/primeiro-acesso/validar` | ✓ | pendente | ✓ | | `POST /publico/primeiro-acesso/senha` | ✓ | pendente | ✓ | | `GET /publico/credenciamento/verificar` | ✓ | pendente | ✓ | | `GET /publico/cep/{cep}` | ✓ | pendente | ✓ | | `POST /publico/credenciamento/solicitar` | ✓ | pendente | ✓ | | `GET /contribuinte/painel/resumo` | ✓ | pendente | ✓ | | `GET /contribuinte/painel/atividades` | ✓ | pendente | ✓ | | `GET /contribuinte/debitos` | ✓ | pendente | ✓ | | `GET /contribuinte/debitos/{id}/guia` | ✓ | pendente | ✓ | | `GET /contribuinte/certidoes` | ✓ | pendente | ✓ | | `GET /contribuinte/certidoes/{id}/pdf` | ✓ | pendente | ✓ | | `GET /contribuinte/alvaras` | ✓ | pendente | ✓ | | `GET /contribuinte/pagamentos` | ✓ | pendente | ✓ | | `GET /contribuinte/pagamentos/{id}/comprovante` | ✓ | pendente | ✓ | | `GET /contribuinte/dados` | ✓ | pendente | ✓ | | `PUT /contribuinte/dados/contato` | ✓ | pendente | ✓ | | `GET /publico/avisos/{dominio}` | parcial | pendente | — |