# Empresas e certificado

Cada CNPJ que vai emitir é uma **empresa** da sua conta. Você cadastra, atualiza, envia o certificado digital e liga a produção pela API, sem depender de ninguém.

| Método | Rota | Para quê |
|---|---|---|
| `GET` | `/empresas` | listar as empresas da conta |
| `POST` | `/empresas` | cadastrar (nasce em homologação) |
| `GET` | `/empresas/{cnpj}` | detalhar |
| `PATCH` | `/empresas/{cnpj}` | atualizar (parcial) |
| `GET` | `/empresas/{cnpj}/certificado` | situação do certificado |
| `PUT` | `/empresas/{cnpj}/certificado` | enviar o certificado A1 |
| `DELETE` | `/empresas/{cnpj}/certificado` | remover o certificado |
| `PUT` | `/empresas/{cnpj}/ambiente` | trocar homologação ↔ produção |

O `{cnpj}` da URL aceita só os dígitos (ou o formato alfanumérico); pontos, barra e traço são ignorados. O CNPJ de outra conta e um CNPJ que não existe recebem a **mesma** resposta `404 empresa_nao_encontrada`: a API nunca revela quem é cliente da plataforma.

## Cadastrar uma empresa

`POST /empresas`

<!-- exemplo:empresa -->
```json
{
  "cnpj": "11.222.333/0001-81",
  "razao_social": "LOJA EXEMPLO LTDA",
  "nome_fantasia": "Loja Exemplo",
  "ie": "111.111.111.111",
  "regime": "simples",
  "uf": "SP",
  "municipio": "Sao Paulo",
  "logradouro": "Rua das Flores",
  "numero": "100",
  "bairro": "Centro",
  "cep": "01001-000",
  "email": "fiscal@loja.exemplo.com.br",
  "telefone": "(11) 99999-8888"
}
```

Resposta `201`:

```json
{
  "id": "d6a1174d-11f5-487e-9583-d846f870c54d",
  "razao_social": "LOJA EXEMPLO LTDA",
  "nome_fantasia": "Loja Exemplo",
  "cnpj": "11222333000181",
  "ie": "111111111111",
  "im": null,
  "cnae": null,
  "regime": "simples",
  "industrial": false,
  "p_cred_sn": null,
  "endereco": {
    "uf": "SP", "codigo_municipio": "3550308", "municipio": "Sao Paulo", "logradouro": "Rua das Flores",
    "numero": "100", "complemento": null, "bairro": "Centro", "cep": "01001000"
  },
  "telefone": "11999998888",
  "email": "fiscal@loja.exemplo.com.br",
  "ambiente": "homologacao",
  "certificado": { "instalado": false, "valido_ate": null, "dias_restantes": null, "vencido": false },
  "bloqueios_producao": [
    "Envie um certificado A1 válido (e-CNPJ).",
    "As tabelas fiscais ainda não foram validadas por um contador (FISCAL_RATES_VERIFIED)."
  ],
  "ativo": true,
  "criado_em": "2026-10-04T15:50:05+00:00"
}
```

### Campos do cadastro

Campo desconhecido é recusado. Obrigatórios no `POST`: `cnpj`, `razao_social`, `regime`, `uf`, `municipio`, `logradouro`, `numero`, `bairro`, `cep`, `email`.

| Campo | Regra |
|---|---|
| `cnpj` | **só no `POST`**; com dígito verificador, numérico ou alfanumérico; único na plataforma |
| `razao_social` | até 60 caracteres (limite da NF-e) |
| `nome_fantasia` | até 60 |
| `ie` | inscrição estadual, 2 a 14 dígitos. Sem IE habilitada na SEFAZ não há NF-e |
| `im`, `cnae` | inscrição municipal (até 15 dígitos); CNAE com 7 dígitos |
| `regime` | `mei`, `simples`, `simples_excesso`, `presumido` ou `real`. **Informe o verdadeiro**: ele decide como o ICMS é calculado (CSOSN no Simples/MEI, CST nos demais) |
| `industrial` | `true` se for estabelecimento industrial (passa a exigir IPI) |
| `p_cred_sn` | percentual de crédito de ICMS do Simples (CSOSN 101), 0 a 100. **Só** para Simples/MEI |
| `uf` | sigla da UF |
| `codigo_municipio` | código IBGE do município (7 dígitos). Se faltar, a API descobre pelo CEP; se não conseguir, pede que você informe |
| `municipio`, `logradouro`, `numero`, `complemento`, `bairro` | endereço do emitente (até 60 caracteres cada) |
| `cep` | 8 dígitos, com ou sem máscara |
| `telefone`, `email` | contato do emitente |

**Limite de empresas:** cada conta tem um máximo de empresas (padrão 50, ajustável). Passou dele: `422 limite_de_empresas`. Criar empresa e enviar certificado são **operações sensíveis**: no máximo 10 chamadas por minuto por chave.

**CNPJ já cadastrado** na plataforma devolve `422` com erro no campo `cnpj` (a mesma mensagem, seja o CNPJ da sua conta ou de outra).

## Atualizar uma empresa

`PATCH /empresas/{cnpj}`: atualização **parcial**. O que você não enviar fica como está, e o **resultado inteiro** é validado. O CNPJ não muda (o certificado e as notas estão presos a ele).

<!-- exemplo:atualizar-empresa -->
```json
{ "nome_fantasia": "Loja Exemplo Centro", "regime": "presumido" }
```

Se você trocar o `cep` sem informar o município, o código IBGE antigo deixa de valer e a API o descobre de novo. Mande `"ativo": false` para **desativar a emissão** da empresa (as notas e o cadastro continuam); `"ativo": true` reativa.

## Certificado digital A1

Para emitir, a SEFAZ exige o **certificado A1** (arquivo `.pfx` ou `.p12`) **e-CNPJ ICP-Brasil** da empresa, dentro da validade. Certificado de pessoa física (e-CPF), A3 (token ou cartão) e autoassinado **não servem**.

`PUT /empresas/{cnpj}/certificado` aceita dois formatos.

**JSON, com o arquivo em base64:**

```bash
curl -s -X PUT "$API/empresas/11222333000181/certificado" -H "Authorization: Bearer $CHAVE" -H "Content-Type: application/json" \
  -d "{\"arquivo_certificado_base64\": \"$(base64 -w0 certificado.pfx)\", \"senha_certificado\": \"SENHA\"}"
```

**Multipart, com o arquivo:**

```bash
curl -s -X PUT "$API/empresas/11222333000181/certificado" -H "Authorization: Bearer $CHAVE" \
  -F "certificado=@certificado.pfx" -F "senha_certificado=SENHA"
```

A API confere que o arquivo abre com a senha, que não está vencido e que o CNPJ do certificado é o da empresa (mesma raiz de 8 dígitos: matriz e filiais compartilham o certificado do grupo). Resposta `200`:

```json
{ "empresa": "LOJA EXEMPLO LTDA:11222333000181", "cnpj": "11222333000181", "valido_ate": "2027-10-04", "dias_restantes": 364 }
```

- Arquivo de até **200 KB**.
- A mensagem de erro para arquivo inválido e senha errada é **a mesma** de propósito (não ajudar quem está sondando): confira o arquivo e a senha.
- O arquivo e a senha ficam **criptografados** e **nunca** voltam em nenhuma resposta nem entram no log.
- `GET /empresas/{cnpj}/certificado` devolve só a situação: `{ "instalado": true, "valido_ate": "2027-10-04", "dias_restantes": 364, "vencido": false }`. **Monitore `dias_restantes`**: certificado vencido bloqueia toda a emissão da empresa.
- `DELETE /empresas/{cnpj}/certificado` remove o certificado; sem ele não há emissão e a empresa **volta para homologação**.

### Cadastrar já com o certificado (tudo ou nada)

O `POST /empresas` aceita `arquivo_certificado_base64` e `senha_certificado` junto dos dados: se o certificado for recusado, **a empresa também não é criada**. É o jeito mais simples de fazer o *onboarding* de um cliente em uma só chamada.

## Trocar de ambiente

`PUT /empresas/{cnpj}/ambiente` com `{ "ambiente": "producao" }` ou `{ "ambiente": "homologacao" }`.

Produção só libera quando **nada impede**. O que falta vem em `erros.ambiente` (e, a qualquer momento, em `bloqueios_producao` da empresa):

```json
{ "codigo": "requisicao_invalida", "mensagem": "As tabelas fiscais ainda não foram validadas por um contador (FISCAL_RATES_VERIFIED).",
  "erros": { "ambiente": ["As tabelas fiscais ainda não foram validadas por um contador (FISCAL_RATES_VERIFIED)."] } }
```

Os bloqueios possíveis são: certificado A1 válido ausente ou vencido, inscrição estadual não informada e as tabelas fiscais da plataforma ainda não validadas. Antes de trocar, siga o [checklist de produção](10-producao.md).

## Numeração da NF-e (séries e próximo número)

Cada empresa numera as notas em sequência, por **série** e por **ambiente** (homologação e produção têm sequências próprias). Sem configurar nada, a nota sai na **série 1** a partir do **número 1**.

Quem já emitia por outro sistema (Bling, Tiny...) precisa **continuar de onde parou**: a SEFAZ recusa número repetido na mesma série. Antes da primeira nota em produção, informe o próximo número:

```bash
curl -s -X PUT "$API/empresas/11222333000181/series/1" -H "Authorization: Bearer $CHAVE" -H "Content-Type: application/json" \
  -d '{ "proximo_numero": 1500 }'
```

Resposta `200`:

```json
{ "cnpj": "11222333000181", "ambiente": "producao", "serie": 1, "ultimo_numero": 1499, "proximo_numero": 1500 }
```

- A série vai de `0` a `889` (890 em diante são do fisco e da contingência). Série que não existe é criada na hora.
- A numeração **só anda para a frente**: número menor ou igual ao maior já usado na série responde `422` `numero_retroativo`, com o `minimo` aceito. Número já usado nunca é reaproveitado.
- O ajuste vale para o **ambiente atual** da empresa. Configure a numeração de produção depois de [trocar de ambiente](#trocar-de-ambiente).
- Pular números sem nota (por exemplo, ir de 10 para 1500 sem ter emitido 11 a 1499 em outro sistema) obriga a [inutilizar](06-eventos.md#inutilizar-numeracao) a faixa pulada.

`GET /empresas/{cnpj}/series` lista as séries do ambiente atual com `ultimo_numero` e `proximo_numero` (sem nenhuma nota, a série 1 aparece com próximo número 1). Para emitir em outra série, mande `serie` no corpo da nota ([Emitir NF-e](05-emitir-nfe.md#nota)).

## Resposta da empresa

Campos que você vai usar mais: `ambiente` (`homologacao` ou `producao`), `certificado.dias_restantes` e `certificado.vencido`, `bloqueios_producao` (lista do que impede a produção; vazia quando pode ligar) e `ativo`.
