Skip to content

Assinaturas e Faturamento

Última atualização: 2026-04-06

Adapter centralizado: Toda comunicação HTTP com o Mercado Pago está em _shared/payment-gateway.ts. Para trocar de provedor, alterar apenas esse arquivo.

Canal de notificação: Lembretes e avisos de faturamento são enviados via WhatsApp (Wasender). Ref: docs/architecture/THIRD_PARTY_INTEGRATIONS.md


1. Planos

Tabela: planos

CampoTipoDescrição
nometextNome do plano
preco_mensalnumericPreço base mensal
preco_anualnumericPreço anual (se aplicável)
valor_por_aluno_extranumericValor por aluno contratado (multiplicado pelo total)
alunos_minimo / alunos_maximointFaixa de elegibilidade
trial_diasintDuração do trial em dias
is_trialboolSe é plano de teste
tipo_cobrancatextmensal ou anual
featuresjsonbFeatures habilitadas

Fórmula de Cálculo

Valor Mensal = Preço Base + (Alunos Contratados × Valor por Aluno Extra)

2. Assinaturas

Tabela: escola_assinaturas

Ciclo Contratual

  • data_inicio → início do contrato
  • meses_contratados → duração total
  • data_fim_contrato → calculado (encerra obrigatoriamente em dezembro)
  • dia_vencimento → dia do mês para faturas
  • renovacao_automatica → se renova ao expirar

Status

StatusSignificado
trialPeríodo de teste (validado por trial_ate)
ativaAssinatura paga ativa
suspensaPagamento atrasado — acesso bloqueado
canceladaCancelamento solicitado
encerradaContrato finalizado

Gateway MercadoPago

CampoUso
gateway_customer_idID do cliente no MercadoPago
gateway_subscription_idID da assinatura (se recorrente)

3. Faturas

Tabela: escola_faturas

Numeração Sequencial

Trigger gerar_numero_fatura gera automaticamente: OLP-2026-0001, OLP-2026-0002, etc.

Status de Pagamento

StatusDescrição
pendenteGerada, aguardando pagamento
pagoPagamento confirmado
atrasadoVencimento ultrapassado
canceladoFatura cancelada

Integração MercadoPago

CampoDescrição
gateway_preference_idPreference ID do Checkout Pro
link_pagamentoURL init_point para pagamento
gateway_payment_idID do pagamento confirmado
pix_qrcode / pix_copia_colaDados PIX
boleto_pdf_url / codigo_barrasDados do boleto
lembrete_d5_enviado_emTimestamp do envio do lembrete D-5 (evita reenvio)

Fluxo de Pagamento

1. Admin gera link → Edge Function cria Preference no MercadoPago
2. preference_id salvo em gateway_preference_id
3. init_point salvo em link_pagamento
4. Usuário clica → redirecionado ao MercadoPago
5. Webhook recebe notificação → valida pagamento → atualiza fatura

4. Geração Automática de Faturas

Job: gerar-faturas-mensal

  • Edge Function: faturamento-cron (action gerar_faturas)
  • Schedule: 0 6 28-31 * * (dias 28-31 de cada mês, 03:00 BRT / 06:00 UTC)
  • Lógica: Roda nos dias 28-31 mas só executa se amanhã.getDate() === 1 (último dia do mês)
  • Regra: Ciclo anual encerra em dezembro — não gera faturas além desse mês

Regra de Ouro: "Sempre Mês Seguinte"

A primeira fatura de novos planos ou alterações é gerada para o primeiro dia do mês subsequente, evitando cobranças imediatas.

Recálculo Automático

Ao alterar alunos_contratados ou dia_vencimento, faturas pendentes futuras são recalculadas automaticamente.


5. Lembrete D-5

Job: lembrete-d5-diario

  • Edge Function: faturamento-cron (action lembrete_d5)
  • Schedule: 0 9 * * * (diariamente, 06:00 BRT / 09:00 UTC)
  • Lógica: Busca faturas pendentes com vencimento em 5 dias que ainda não receberam lembrete (lembrete_d5_enviado_em IS NULL)
  • Canal: Mensagem enviada via WhatsApp (Wasender) para o contato da escola
  • Controle: Após envio bem-sucedido, marca lembrete_d5_enviado_em = now() para evitar reenvios

Comportamento

CenárioAção
Fatura pendente, vence em 5 dias, sem lembreteEnvia WhatsApp + marca timestamp
Fatura pendente, vence em 5 dias, já lembradaIgnora (idempotente)
Fatura paga ou canceladaIgnora

6. Trial

Verificação: subscription-helper.ts

typescript
const resultado = await verificarAssinaturaEscola(supabase, escolaId, 'sistema');
if (!resultado.valida) {
  // resultado.code: 'TRIAL_EXPIRADO' | 'SEM_ASSINATURA'
}

Comportamento

CenárioResultado
Assinatura ativa ou trial válidovalida: true
Trial expiradovalida: false, code: 'TRIAL_EXPIRADO'
Sem assinaturavalida: false, code: 'SEM_ASSINATURA'
Erro técnicovalida: true (fail-open)

Onde é Verificado

ContextoEdge Function
Login sistemasend-otp, verify-otp
Portal alunoportal-escola (lookup)

7. Administração

Edge Functions

FunçãoAções Principais
admin-assinaturasCRUD de assinaturas, recálculo de faturas
admin-faturasListagem, geração manual de links, marcação de pago
admin-planosCRUD de planos
admin-escola-dadoscreate_assinatura — criação de assinatura na tela de detalhes da escola
escola-pagamentosVisão da escola: faturas, links de pagamento (usado por gestão/diretor)
mercadopago-preferenceGerar link de pagamento (Checkout Pro)
mercadopago-webhookReceber notificações de pagamento
faturamento-cronGeração mensal de faturas + lembrete D-5

Hooks Frontend

HookUso
useAdminAssinaturasGestão de assinaturas (admin)
useAdminFaturasGestão de faturas (admin)
useAdminPlanosGestão de planos (admin)
useMercadoPagoGeração de links e polling (admin)
useEscolaPagamentosFaturas e pagamentos (visão escola — gestão/diretor)

8. Faturas Migradas

Faturas importadas de sistemas legados são marcadas com migrada = true. Não possuem gateway_preference_id e servem apenas como histórico financeiro.


9. Auto-Ativação de Escola

Ao ativar uma assinatura paga (status_assinatura = 'ativa'), se a escola estiver com status = 'em_analise', seu status é automaticamente alterado para ativa.

Regra conservadora: Só ativa escolas em em_analise. Escolas já ativa, suspensa ou encerrada não são alteradas.

Pontos de ativação (3 caminhos):

Edge FunctionActionContexto
admin-escola-dadoscreate_assinaturaTela de detalhes da escola
admin-assinaturascreateTela de assinaturas
admin-assinaturasconvert_trial_to_paidConverter trial para pago

10. Referências