Notificações WhatsApp
Permite que responsáveis assinem um serviço de notificações via WhatsApp para receber alertas de entrada, saída e falta dos alunos. O faturamento recorrente é processado pelo gateway de pagamento Asaas; a ativação e a suspensão do serviço são automáticas conforme o ciclo financeiro.
Visão geral da arquitetura
A funcionalidade é composta por quatro camadas que trabalham de forma coordenada.
Habilitação por cliente (Admin)
O administrador da plataforma habilita a funcionalidade whatsapp-notifications
para um cliente específico via painel administrativo. Sem essa habilitação, o responsável não vê a opção de assinatura no app.
Assinatura pelo responsável (App móvel)
O responsável escolhe um plano e uma forma de pagamento (PIX ou cartão de crédito). A plataforma cria
o cliente e a assinatura recorrente no Asaas e retorna a URL de checkout hospedada pelo Asaas
(invoice_url).
Nenhum dado de cartão transita pela nossa infraestrutura — a cobrança é inteiramente PCI-compliant no lado do Asaas.
Ativação automática via webhook (Asaas → Plataforma)
O Asaas envia eventos de pagamento e assinatura para o endpoint
POST /webhook/asaas.
O evento PAYMENT_CONFIRMED
ativa a assinatura; SUBSCRIPTION_DELETED
a cancela. O estado da assinatura local é sempre espelho do estado financeiro no Asaas.
Envio condicionado ao status financeiro
No momento de enviar uma notificação WhatsApp (entrada, saída, falta), o
NotificationService
verifica se o responsável possui uma assinatura com status
ACTIVE.
Se não possuir, a mensagem não é enviada, independentemente dos toggles de notificação.
Fluxo de dados resumido
- → Admin habilita
whatsapp-notificationspara o cliente - → Parceiro consulta
GET /v1/partners/school/{cnpj}/responsible/{cpf}/whatsapp/subscription - → Responsável escolhe plano → Parceiro chama
POST /v1/partners/school/{cnpj}/responsible/{cpf}/whatsapp/subscribe - → Plataforma cria customer + subscription no Asaas → retorna
invoice_url - → Responsável paga via checkout Asaas (PIX / cartão)
- → Asaas dispara
PAYMENT_CONFIRMED→ webhook ativa assinatura local - → Parceiro faz polling em
GET /v1/partners/school/{cnpj}/responsible/{cpf}/whatsapp/subscription/statusatéACTIVE - → WhatsApp começa a ser enviado nas notificações de entrada / saída / falta
Regras de negócio
Habilitação e acesso
- •A funcionalidade deve ser habilitada individualmente para cada cliente pelo administrador da plataforma. Sem ela, a assinatura é bloqueada com
HTTP 403. - •Cada responsável pode ter no máximo uma assinatura ativa ou pendente por vez. Tentativas de criar uma segunda assinatura enquanto existe uma bloqueante retornam
HTTP 409. - •Statuses que bloqueiam nova assinatura:
PENDING,ACTIVE,OVERDUE,PAST_DUE,PAUSED.
Ciclo de cobrança
- •O ciclo padrão é mensal (
MONTHLY), configurável por plano. - •A primeira cobrança é gerada imediatamente (data de vencimento = hoje). As cobranças subsequentes seguem o ciclo do plano.
- •A assinatura é criada com status
PENDINGno banco de dados local. A ativação ocorre exclusivamente por webhook (PAYMENT_CONFIRMED). - •Formas de pagamento aceitas por plano são definidas no campo
billing_typesdoSubscriptionPlan. O padrão é["PIX", "CREDIT_CARD"].
Ativação e suspensão do serviço WhatsApp
- •O envio de mensagens WhatsApp é condicionado a uma assinatura com status
ACTIVE. Todos os demais statuses suspendem o envio. - •O sistema verifica o status no momento do disparo (entrada, saída, falta), não em cache. Uma assinatura que passe para
OVERDUEpara de receber mensagens imediatamente após o webhook. - •Os toggles de notificação (
whatsapp_checkin,whatsapp_checkout,whatsapp_absence) são verificados adicionalmente — a mensagem só é enviada se o toggle estiver ativo e a assinatura estiver ativa.
Dados necessários para criar cliente no Asaas
- •O responsável deve ter o campo
cpfpreenchido. - •O responsável deve ter um nome associado via perfil de usuário.
- •Se CPF ou nome estiverem ausentes, a assinatura é bloqueada com
HTTP 422. - •O cliente no Asaas é criado uma única vez e reutilizado em assinaturas subsequentes (busca por CPF antes de criar).
PENDING
Assinatura criada, aguardando primeiro pagamento.
ACTIVE
Pagamento confirmado. WhatsApp ativo.
OVERDUE
Pagamento em atraso. Serviço suspenso.
PAST_DUE
Período de tolerância expirado.
PAUSED
Pausada temporariamente pelo Asaas.
CANCELED
Cancelada pelo responsável ou plataforma.
EXPIRED
Assinatura encerrada por prazo.
FAILED
Falha no pagamento / chargeback.
O modelo assinatura
Representa uma assinatura recorrente de um responsável a um plano de notificações WhatsApp. O modelo é criado localmente no momento da requisição e sincronizado com o Asaas via webhooks.
id
string (uuid)
Identificador local da assinatura. É enviado ao Asaas como externalReference.
status
string
Status financeiro: PENDING, ACTIVE, OVERDUE, PAST_DUE, PAUSED, CANCELED, EXPIRED, FAILED.
billing_type
string
Forma de pagamento: PIX ou CREDIT_CARD.
cycle
string
Ciclo de cobrança: MONTHLY, QUARTERLY, SEMIANNUALLY, YEARLY.
value
number
Valor cobrado por ciclo, em reais.
next_due_date
string (Y-m-d)
Data de vencimento da próxima cobrança.
asaas_subscription_id
string
ID da assinatura no Asaas (sub_...). Null até a confirmação do Asaas.
asaas_customer_id
string
ID do cliente no Asaas (cus_...).
activated_at
string (ISO 8601)
Data/hora em que a assinatura foi ativada pela primeira vez.
canceled_at
string (ISO 8601)
Data/hora do cancelamento. Null se ainda ativa.
plan
object
Plano associado: { id, name }.
created_at
string (ISO 8601)
Data/hora de criação do registro.
{ "id": "019e9326-6dad-705e-afe2-34d494ee0694", "status": "ACTIVE", "billing_type": "PIX", "cycle": "MONTHLY", "value": 49.9, "next_due_date": "2026-07-04", "asaas_subscription_id": "sub_a1B2c3D4e5F6", "asaas_customer_id": "cus_X9y8Z7w6", "activated_at": "2026-06-04T12:05:00+00:00", "canceled_at": null, "plan": { "id": "9b1f4a72-0000-0000-0000-000000000001", "name": "WhatsApp Essencial" }, "created_at": "2026-06-04T12:00:00+00:00" }
/v1/partners/school/{cnpj}/responsible/{cpf}/whatsapp/subscription
Estado + planos disponíveis
Retorna se a funcionalidade está habilitada para o cliente do responsável autenticado, a assinatura atual (se houver) e o catálogo de planos disponíveis. Deve ser chamado ao carregar a tela de configurações de notificações.
Autenticação
Requer os três cabeçalhos de parceiro:
X-Partner— token do parceiroX-Client— identificador do cliente (escola)X-Authorization— token de API do cliente
Campos da resposta
feature_enabled
boolean
Se true, a funcionalidade está habilitada para o cliente. Se false, esconder a seção no app.
has_active_subscription
boolean
Se true, o responsável já possui uma assinatura ACTIVE.
current
object|null
Objeto assinatura atual. Null se não houver nenhuma.
plans
array
Lista de planos disponíveis com id, name, description, features, price, cycle, billing_types.
Lógica de apresentação no app
feature_enabled = false→ ocultar toda a seção WhatsApphas_active_subscription = false→ exibir botão "Assinar WhatsApp"has_active_subscription = true→ mostrar toggles + "Cancelar assinatura"
{ "feature_enabled": true, "has_active_subscription": false, "current": null, "plans": [ { "id": "9b1f4a72-0000-0000-0000-000000000001", "name": "WhatsApp Essencial", "description": "Notificações de entrada, saída e falta.", "features": ["Entrada", "Saída", "Falta"], "price": 49.9, "cycle": "MONTHLY", "billing_types": ["PIX", "CREDIT_CARD"] } ] }
/v1/partners/school/{cnpj}/responsible/{cpf}/whatsapp/subscribe
Assinar um plano
Cria uma assinatura recorrente no Asaas para o responsável autenticado e retorna os dados
de checkout. A assinatura é criada localmente com status PENDING
e ativada automaticamente quando o Asaas confirmar o pagamento via webhook.
Corpo da requisição
subscription_plan_id
string (uuid) — obrigatório
ID do plano escolhido. Deve ser um plano ativo com feature_key = whatsapp-notifications.
billing_type
string — obrigatório
Forma de pagamento: PIX ou CREDIT_CARD. Deve estar no array billing_types do plano.
Campos da resposta (201)
subscriptionobjectO modelo assinatura criado com status PENDING.
invoice_urlstring|nullURL de checkout hospedada pelo Asaas. Abra em WebView ou browser externo. Nenhum dado de cartão passa pela plataforma.
pix_qr_codeobject|nullQR code PIX: encodedImage (PNG base64), payload (copia-e-cola), expirationDate. Null para cartão de crédito.
Erros possíveis
403
Funcionalidade não habilitada para o cliente.
409
Responsável já possui assinatura ativa ou pendente.
422
billing_type não permitido pelo plano ou dados de perfil (CPF/nome) ausentes.
502
Erro no gateway Asaas. O erro é registrado em integration_logs.
POST /api/v1/partners/school/{cnpj}/responsible/{cpf}/whatsapp/subscribe X-Partner: <partner-token> X-Client: <client-name> X-Authorization: <client-token> Content-Type: application/json { "subscription_plan_id": "9b1f4a72-0000-0000-0000-000000000001", "billing_type": "PIX" }
{ "message": "Assinatura iniciada. Conclua o pagamento...", "subscription": { /* objeto assinatura */ }, "invoice_url": "https://www.asaas.com/i/abc123", "pix_qr_code": { "encodedImage": "iVBORw0KGgo...", "payload": "00020126...", "expirationDate": "2026-06-05 23:59:59" } }
/v1/partners/school/{cnpj}/responsible/{cpf}/whatsapp/subscription/status
Consultar status da assinatura
Retorna o status atual da assinatura do responsável autenticado. Use este endpoint para polling após redirecionar o responsável ao checkout do Asaas, detectando a ativação.
Estratégia de polling recomendada
Faça polling a cada 3–5 segundos por no máximo 2 minutos enquanto o responsável
estiver na tela de aguardo. Pare quando has_active_subscription
for true ou o responsável sair da tela.
Campos da resposta
has_active_subscriptionbooleanTrue quando status = ACTIVE. Use este campo para habilitar os toggles de notificação no app.
currentobject|nullO modelo assinatura mais recente do responsável. Null se não houver nenhuma.
{ "has_active_subscription": true, "current": { "id": "019e9326-6dad-...", "status": "ACTIVE", "billing_type": "PIX", "cycle": "MONTHLY", "value": 49.9, "next_due_date": "2026-07-04", "activated_at": "2026-06-04T12:05:00+00:00", "canceled_at": null, "plan": { "id": "...", "name": "WhatsApp Essencial" }, "created_at": "2026-06-04T12:00:00+00:00" } }
/v1/partners/school/{cnpj}/responsible/{cpf}/whatsapp/subscription
Cancelar assinatura
Cancela a assinatura ativa do responsável identificado pelo CPF. O cancelamento é propagado ao Asaas
(encerrando cobranças futuras) e o status local é atualizado para
CANCELED.
O registro histórico é preservado.
Erros possíveis
404
Não existe assinatura ativa para cancelar.
502
Erro ao cancelar no Asaas. O erro é registrado em integration_logs.
{ "message": "Assinatura cancelada com sucesso." }