# Fluxo de assinaturas e cobranças Asaas

## Pré-requisitos de implantação

1. Aplicar `database/2026-07-15-001-fluxo-assinaturas-asaas.sql` antes de publicar o backend.
2. Configurar `ASAAS_API_KEY`, `ASAAS_API_URL` e `ASAAS_WEBHOOK_TOKEN` no ambiente. O token do webhook deve ser diferente da API Key, ter ao menos 32 caracteres e ser configurado também no Asaas.
3. Apontar o webhook Asaas para `POST /webhook/asaas`.
4. Agendar `php back/bin/processar-assinaturas.php` (recomendação: a cada 15 minutos).
5. Validar o fluxo completo em Sandbox antes de usar credenciais de produção.

## Estados locais

- `TRIAL`: teste grátis vigente, sem cobrança.
- `PENDING_PAYMENT`: teste encerrado ou primeira cobrança aguardando pagamento.
- `ACTIVE`: existe período pago vigente.
- `OVERDUE`: cobrança vencida, mas o período pago/tolerância ainda pode permitir acesso.
- `SUSPENDED`: acesso bloqueado por inadimplência sem período válido, estorno ou chargeback.
- `CANCELED`: novas renovações desativadas; um período já pago continua válido.
- `EXPIRED`: cancelamento chegou ao fim do período contratado.

## Fluxo

O cadastro valida o plano no backend. Se o plano estiver ativo, permitir teste e o usuário optar pelo teste sem tê-lo usado antes, é criada uma assinatura local `TRIAL`, sem fatura, cliente Asaas ou cobrança. O job encerra o trial, cria uma única fatura pendente e muda a assinatura para `PENDING_PAYMENT`.

Ao pagar, o backend carrega conta, plano, cupom e fatura; o frontend não define o preço. O cliente Asaas é recuperado pelo ID persistido ou conciliado por CPF/CNPJ. A cobrança recebe `externalReference` e chave de idempotência. Uma cobrança pendente válida é reutilizada; ao trocar o meio, a anterior precisa ser cancelada antes da nova.

Pix e boleto permanecem pendentes até o webhook. Cartão é tokenizado em rota privada vinculada à conta. A resposta síncrona nunca libera acesso. Quando a renovação automática é autorizada, o Asaas agenda a próxima cobrança e o banco guarda somente IDs, bandeira/final quando disponíveis — nunca número completo ou CVV.

O webhook valida `asaas-access-token`, persiste o `id` único do evento, processa em transação e responde não-2xx em falhas para permitir retry. Apenas a primeira transição de um pagamento para `approved` estende o período contratado. Eventos tardios não regridem um pagamento confirmado; estorno e chargeback continuam sendo estados terminais e suspendem acesso.

## Rotas adicionadas

- `POST /private/pagamento/cartao/tokenizar/{id_conta}`: tokeniza cartão usando cliente e titular derivados no backend.
- `GET /private/assinatura/{id_conta}`: consulta estado e acesso.
- `DELETE /private/assinatura/{id_conta}/renovacao`: cancela somente futuras renovações e preserva período pago.
- `POST /root/webhooks/asaas/reprocessar/{id_evento_local}`: reprocessa evento armazenado.
- `DELETE /root/assinaturas/{id_conta}/cancelar`: cancelamento administrativo imediato.

As rotas legadas foram preservadas. `POST /public/cartao/tokenizar` continua existente por compatibilidade, mas agora exige JWT e usa a conta autenticada.

## Eventos tratados

O processador usa o `payment.status` para abranger `PENDING`, `RECEIVED`, `CONFIRMED`, `RECEIVED_IN_CASH`, `OVERDUE`, `REFUNDED`, `PARTIALLY_REFUNDED`, `REFUND_REQUESTED`, `REFUND_IN_PROGRESS`, `CHARGEBACK_REQUESTED`, `CHARGEBACK_DISPUTE`, `AWAITING_CHARGEBACK_REVERSAL`, `DELETED`, `AWAITING_RISK_ANALYSIS` e recebimento por cobrança (`DUNNING_RECEIVED`). Eventos de assinatura `ACTIVE`, `INACTIVE` e `EXPIRED` também são conciliados.

Isso cobre os eventos de pagamento criado/atualizado, confirmado/recebido, vencido, removido/restaurado, estornado, em análise de risco, chargeback e assinatura enviados pelo Asaas, inclusive duplicados e fora de ordem.

## Operação e auditoria

- `asaas_webhook_eventos`: payload, resultado, tentativas e erro reprocessável.
- `assinaturas_historico`: trial, plano, pagamento, cancelamento e mudanças de status.
- `asaas_processamento_tentativas`: resumo sanitizado das chamadas de cobrança.
- `idempotencia_operacoes`: lock e resultado das operações externas.

Não registrar payload de cartão, tokens de autenticação ou API Keys em logs. Monitorar eventos `FAILED`, tentativas com `sucesso = 0` e filas pausadas no painel do Asaas.
