Files
Condominio_SeConectai/Schemas/07-financeiro-abacatepay.md
T
2026-09-29 12:12:31 -03:00

64 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Prompt 07 — Financeiro: assinaturas, período de uso e AbacatePay
## Contexto
Prompts 01–06 concluídos: CRUD completo do escritório funcionando. **Leia `10-tracker-progresso.md` antes de começar.**
Este prompt implementa o menu **Cliente → Financeiro** (pagar mensalidade) e a automação de bloqueio/liberação de acesso conforme pagamento, usando AbacatePay para gerar cobrança PIX.
## Objetivo
Criar/consultar `periodos_uso` do mês corrente, gerar cobrança PIX via AbacatePay, processar o webhook de confirmação, e rodar o job diário que bloqueia empresas inadimplentes.
## Especificação
### 1. Cliente AbacatePay
Consultar a documentação oficial da AbacatePay (https://docs.abacatepay.com) para confirmar o formato exato do endpoint de criação de cobrança PIX e do payload do webhook — **não assumir o formato sem checar**, a API pode ter mudado. Implementar `AbacatePayClient`:
- `criarCobranca(valorCentavos, descricao, identificadorExterno)` → retorna `{chargeId, qrCodePayload, qrCodeBase64}`
- Validação de assinatura do webhook, se a AbacatePay oferecer esse mecanismo (verificar na doc).
### 2. Endpoints do escritório
```
GET /api/financeiro/periodo-atual
→ busca (ou cria, se não existir) o periodos_uso do mes_referencia = mês corrente;
retorna status, valor da assinatura vigente, se já tem pagamento pendente/gerado
POST /api/financeiro/pagamentos
→ se já existe um pagamento 'pendente' pro período atual, retorna ele (não duplica
cobrança); senão, chama AbacatePayClient.criarCobranca com o valor da assinatura,
grava em `pagamentos`, retorna qr_code_base64 + qr_code_payload pro frontend renderizar
GET /api/financeiro/pagamentos/{id}
→ status atual (útil pro frontend fazer polling enquanto o QR Code está na tela)
```
### 3. Webhook
```
POST /api/master/webhooks/abacatepay
→ SEM autenticação de master/funcionário (é a AbacatePay chamando) — validar por
assinatura/segredo do webhook, conforme a documentação da AbacatePay
→ identifica o pagamento pelo abacatepay_charge_id, marca status='pago', pago_em=now()
→ marca periodos_uso.status='pago', data_liberacao=now()
→ marca empresas.status='ativa' (caso estivesse 'bloqueada')
→ idempotente: se o webhook chegar duplicado (mesma cobrança já processada), não fazer
nada de errado, só retornar 200 de novo
```
### 4. Job de bloqueio diário
`BloqueioJob`, rodando uma vez por dia (implementar com um `ScheduledExecutorService` simples dentro da própria aplicação Java — não precisa de cron externo nesta fase):
1. Para cada `empresa` com status='ativa': busca (ou cria) o `periodos_uso` do mês corrente.
2. Se `hoje > dia_vencimento` da assinatura E `periodos_uso.status != 'pago'`: marca `periodos_uso.status='bloqueado'`, `data_bloqueio=now()`, `empresas.status='bloqueada'`.
3. Logar quantas empresas foram bloqueadas na execução.
### 5. Bloqueio de acesso
No middleware `exigirFuncionario` (Prompt 04), adicionar a checagem: se `empresas.status='bloqueada'`, retornar 403 com corpo `{"erro": "pendencia_financeira", "mensagem": "..."}` em vez de deixar passar — mas **sempre permitir** o próprio `GET /api/financeiro/periodo-atual` e `POST /api/financeiro/pagamentos` mesmo bloqueado, senão o escritório não consegue nem pagar pra desbloquear.
## Critérios de aceite
- [ ] `POST /api/financeiro/pagamentos` gera de fato uma cobrança na AbacatePay (testar em ambiente sandbox, se a AbacatePay oferecer) e retorna QR Code válido.
- [ ] Chamar `POST /api/financeiro/pagamentos` duas vezes seguidas não cria duas cobranças, retorna a mesma pendente.
- [ ] Simular o webhook (chamada manual com um payload de teste) marca o período como pago e desbloqueia a empresa.
- [ ] Rodar o webhook duas vezes com o mesmo `charge_id` não causa erro nem duplica nada.
- [ ] `BloqueioJob` rodado manualmente (chamar o método direto, sem esperar o schedule) bloqueia corretamente uma empresa de teste com vencimento no passado e sem pagamento.
- [ ] Empresa bloqueada consegue logar e acessar só `/api/financeiro/**`; qualquer outro endpoint retorna 403 com o erro `pendencia_financeira`.
## Ao concluir
Atualizar `10-tracker-progresso.md`: Prompt 07 concluído, data, resumo. Confirmar Prompts 01–06 seguem marcados.