portal-modumfiscal-web/docs/api-backend.md
GUILHERME e4c468e61e
All checks were successful
Dev Build & Deploy Portal / build-deploy (push) Successful in 2m58s
feat(portal): extratos reais, certidão dinâmica e filtros self-scoped
Integra débitos, pagamentos e guias emitidas com API via composables e modais de extrato. Simplifica filtros do portal ao escopo do contribuinte logado. Refatora emissão pública de certidão com modelos dinâmicos e contrato idModelo. Corrige status de taxas (2=Paga, 3=Cancelada) e melhorias no proxy BFF/Keycloak.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 16:21:59 -03:00

17 KiB

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):

{
  "timestamp": "2025-05-18T10:00:00Z",
  "statusCode": 200,
  "responseType": "SUCCESS",
  "message": "OK",
  "data": { }
}

Envelope de erro:

{
  "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: <id_municipio>
  • X-Dominio: <subdominio>

Prefeitura (bootstrap)

GET /publico/prefeitura/{dominio}

Retorna a configuração visual e institucional da prefeitura.

Response data:

{
  "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:

{
  "situacao": "NEGATIVA",
  "nomeContribuinte": "João da Silva Santos"
}

situacao possíveis: NEGATIVA · POSITIVA · POSITIVA_EFEITOS_NEGATIVA


GET /publico/certidao/modelos

Lista modelos de certidão públicos disponíveis para o contribuinte, filtrados pelo cadastro.tipo (PF=1, PJ=2) — paridade com o combo do core.

Query params:

Param Tipo Obrigatório Descrição
documento string sim CPF/CNPJ sem formatação — resolve o destinatário via cadastro
titulo string não Filtro parcial no título do modelo
page int não Página (default: 0)
size int não Tamanho (default: 50)

Response data:

{
  "paginasTotais": 1,
  "elementosTotais": 2,
  "data": [
    {
      "id": 12,
      "titulo": "Certidão Negativa de Débitos",
      "descricaoTipoCertidao": "Certidão Negativa",
      "validadeDias": 180,
      "destinatario": 1
    }
  ]
}

Filtros aplicados no backend: destinatario = tipo do cadastro · publico=1 · vigência válida · modelo com arquivo DOCX anexado.


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
idModelo long sim ID do modelo selecionado em /modelos
finalidade string não Finalidade informada pelo contribuinte (default: "Emissão pelo portal público")

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:

{
  "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:

{
  "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:

{
  "documento": "12345678900",
  "canal": "EMAIL"
}

Response data:

{ "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:

{
  "documento": "12345678900",
  "codigo": "123456"
}

Response data:

{ "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:

{
  "token": "eyJhb...",
  "senha": "MinhaS3nha!"
}

Response data:

{ "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:

{ "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:

{
  "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):

{
  "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):

{
  "tipoPessoa": "JURIDICA",
  "razaoSocial": "Empresa LTDA",
  "nomeFantasia": "Empresa",
  "inscricaoEstadual": "12345678",
  "representanteLegal": {
    "nomeCompleto": "João da Silva",
    "cpf": "12345678900",
    "cargo": "Diretor"
  }
}

Response data:

{ "protocolo": "CRED-2025-00123" }

Módulo Portal — requer autenticação

Header obrigatório além dos de tenant:

  • Authorization: Bearer <jwt_keycloak>

Painel

GET /contribuinte/painel/resumo

Dados do card de resumo do dashboard.

Response data:

{
  "totalDebitos": 1250.90,
  "certidoesAtivas": 2,
  "alvarasAndamento": 2,
  "ultimoPagamento": 430.00,
  "debitosVencidos": 1
}

GET /contribuinte/painel/atividades

Lista das últimas atividades do contribuinte.

Response data:

{
  "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 (Extrato)

GET /contribuinte/debitos

Lista débitos agrupados por conta/tributo (ContaCorrenteTributoDTO), com os mesmos filtros do extrato interno.

Query params: idTaxa, idContaTributo, periodoIni (YYYYMM), periodoFim (YYYYMM), inscMunicipal, idEstadoConta (1=débito, 2=zero, 3=crédito)

Response data: array de ContaCorrenteTributoDTO com lista debitos aninhada.


GET /contribuinte/debitos/tributos/{codigo}

Busca tributo por código para filtros.


GET /contribuinte/debitos/contas-tributo/{codigo}

Busca conta tributo por código para filtros.


GET /contribuinte/debitos/{idContaCorrente}/transacoes

Transações da conta corrente (somente se pertencer ao contribuinte logado).


POST /contribuinte/debitos/gerar-guia

Gera guia para débitos selecionados. Body: GerarGuiaDebitosRequestDTO.

Response data: GerarGuiaResponseDTO (idDoctoArr, numeroGuia, etc.)


GET /contribuinte/debitos/guia/{idDoctoArr}

PDF de guia já emitida (validação de ownership).


GET /contribuinte/debitos/{idContaCorrente}/guia

Gera e retorna PDF de guia para um único débito.


POST /contribuinte/debitos/extrato-pdf

Gera PDF do extrato de débitos. Body: GerarExtratoDebitosRequestDTO.

Response: application/pdf


Certidões

GET /contribuinte/certidoes

Lista todas as certidões emitidas pelo contribuinte.

Response data:

{
  "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:

{
  "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 (Extrato)

GET /contribuinte/pagamentos

Lista pagamentos agrupados por tributo (ExtratoPagamentoTributoDTO).

Query params: idTaxa, idContaTributo, pagInicio, pagFim, periodoIni, periodoFim, ano (atalho para intervalo anual)

Response data: array com pagamentos aninhados (principal, multa, juros, desconto, total).


POST /contribuinte/pagamentos/extrato-pdf

Gera PDF do extrato de pagamentos. Body: GerarExtratoPagamentosRequestDTO.

Response: application/pdf


GET /contribuinte/pagamentos/{idContaCorrente}/comprovante

Baixa comprovante de pagamento em PDF (quando houver LancamentoTaxa vinculado).

Response: application/pdf ou 404


Guias Emitidas

GET /contribuinte/guias

Lista guias do contribuinte logado (CPF/CNPJ injetado no backend). Paginado.

Query params: numeroGuia, dataEmissaoInicio/Fim, dataVencimentoInicio/Fim, status, valorMinimo, valorMaximo, page, size

Response data: PageDTO<GuiaConsultaDTO>


GET /contribuinte/guias/{id}

Detalhes completos da guia (GuiaPagamentoDTO).


GET /contribuinte/guias/{id}/pdf

PDF da guia.


Dados Cadastrais

GET /contribuinte/dados

Retorna os dados cadastrais completos do contribuinte autenticado.

Response data (Pessoa Física):

{
  "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):

{
  "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:

{
  "email": "novo@email.com",
  "telefone": "98991234567",
  "whatsapp": true
}

telefone deve ser enviado sem formatação (apenas dígitos).

Response data:

{ "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:

{
  "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
GET /publico/certidao/modelos
GET /publico/certidao/emitir
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