Skip to content

Runbook — falha de webhook EMIS/Unitel

Procedimento de suporte quando o pagamento foi feito (terminal, app ou Multicaixa) mas a fatura no SIGA continua em aberto.

Triagem rápida (60 segundos)

text
Encarregado pagou?
  ├─ Não → orientar pagamento / referência em /faturas
  └─ Sim → fatura ainda open no SIGA?
        ├─ Não (paid) → informar recibo; fim
        └─ Sim → seguir runbook abaixo

Prioridade imediata: se o dinheiro saiu da conta do pagador, a tesouraria pode confirmar manualmente na fatura (PaymentReferenceCard → confirmar pagamento) enquanto se investiga o webhook. Isto não substitui corrigir a integração — evita bloqueio operacional.

Informação a recolher

Preencher antes de escalar:

CampoExemplo
Escola (slug / hostname)colegio-esperanca.portal-siga.com
CanalMulticaixa (/gateway/confirm) ou Unitel (/unitel/confirm)
ID ou n.º da faturaUUID ou FAT-2026-…
Referência EMIS (9 dígitos)123456789
Montante pago (Kz inteiros)45000
Data/hora do pagamento
HTTP status + corpo JSON do webhookdo portal banco ou logs
Comprovativo do pagadorSMS, recibo ATM, captura app

Mapa HTTP → acção

Respostas do SIGA (POST …/gateway/confirm ou …/unitel/confirm):

HTTPMensagem típicaCausaQuem resolveAcção
401API key inválidamerchantId ou chave errada no portalEscola + bancoCopiar webhookApiKey de Definições → Integrações; não usar entidade EMIS como key
401Escola não identificadaIntegração inactiva ou key de outra escolaEscolaReinstalar integração; verificar tenant
400Corpo JSON inválidoPortal envia formato erradoBanco / integradorValidar JSON; Content-Type application/json
400Modo dev: invoiceId em faltaSimulador sem invoiceIdDevAdicionar invoiceId ao corpo
404Fatura não encontradaUUID errado ou fatura de outra escolaEscolaConfirmar invoiceId na fatura SIGA
404Plano ou fatura não encontradosSem plano pending_gateway ou referência erradaEscolaReemitir referência; criar plano gateway
409Referência não coincideReferência do portal ≠ plano SIGAEscola + bancoComparar dígitos; regenerar em /faturas
502Erro ao liquidar / permissões SGARPC register_payment falhouOperador plataformaSQL SGA; confirmar manual na tesouraria
200 + «já liquidada»IdempotênciaWebhook repetidoNormal; verificar recibo existente
Timeout / sem respostaRede / DNS / TLSHostname inacessível, certificadoOperador + escolaTestar URL pública; ADMIN /domains

Passos por perfil

Administrador escolar (tesouraria)

  1. Abrir /faturas → fatura em questão.
  2. Ver Referência EMIS e montante — comparar com comprovativo.
  3. Se pagamento confirmado pelo encarregado: Confirmar manualmente (PaymentReferenceCard).
  4. Definições → Integrações → copiar URL + API key correctas para o banco.
  5. Multicaixa: confirmar Merchant EMIS (não 99824 em produção).
  6. Unitel: URL deve ser /api/finance/gateway/unitel/confirm, não a rota Multicaixa.

Operador SIGA Plus (plataforma)

  1. ADMIN /tenants — escola activa, subscrição não suspensa.
  2. ADMIN /domains — hostname active, SSL ok.
  3. Pedir à escola: slug, invoiceId, referência, timestamp do webhook.
  4. Reproduzir com simulador (staging):
sh
npm run siga:gateway-simulate -- --invoice-id=<uuid> [--amount=45000]
npm run siga:gateway-simulate -- --invoice-id=<uuid> --unitel
  1. Se 502 com mensagem de permissões: escola precisa de SQL SGA (npm run siga:sqlAPPLY_IN_SQL_EDITOR.sql).
  2. Registar em ticket interno: tenant_id, school_id, invoice_id, status HTTP, message.

Banco / EMIS / Unitel (externo)

  1. Confirmar URL de callback exacta (hostname público da escola).
  2. Confirmar corpo POST inclui apiKey, reference, amount (Kz inteiros).
  3. Reenviar webhook de teste com mesma referência e montante da fatura SIGA.
  4. Fornecer logs do lado deles (timestamp, HTTP status recebido, corpo resposta).

Escalonamento

NívelQuandoDestino
L1Dúvida de referência ou confirmação manualSecretaria / tesouraria escolar
L2401/404/409 persistente após verificar IntegraçõesSuporte SIGA Plus (operador)
L3502, hostname, multi-tenant, SQL SGAEquipa técnica plataforma
L4Portal banco não envia webhook ou envia formato inválidoGestor contrato EMIS/Unitel da escola

SLA sugerido: L1 resolve no mesmo dia útil (confirmação manual). L2–L3 em 1–2 dias úteis com dados completos da tabela acima.

Observabilidade

Cada chamada ao webhook (sucesso ou falha) fica registada na tabela finance_gateway_webhook_events e em log JSON (tag: gateway-webhook). A tesouraria vê os últimos 5 eventos em Definições → Integrações (Multicaixa / Unitel).

Operador plataforma

Painel ADMIN → Webhooks gateway (/gateway-webhooks): totais 24h/7d, falhas recentes cross-tenant, escolas com mais falhas na semana.

sh
# Últimos 20 eventos (todas as escolas)
npm run siga:gateway-events-recent

# Só falhas
npm run siga:gateway-events-recent -- --failures-only

# Limite customizado
npm run siga:gateway-events-recent -- --limit=50

Requer SUPABASE_URL + SUPABASE_SECRET_KEY no .env. Se a tabela não existir, executar npm run siga:sqlAPPLY_IN_SQL_EDITOR.sql.

Alertas Slack (opcional)

Defina SIGA_GATEWAY_ALERT_SLACK_URL (Incoming Webhook) no ambiente de produção do SIGA. Falhas com HTTP ≥ 400 disparam uma mensagem compacta (canal, escola, referência mascarada, mensagem).

Alerta de taxa de falha 24h (plataforma)

Quando a taxa de falha nas últimas 24h excede 25% (mínimo 5 eventos), o SIGA pode alertar a equipa de plataforma:

VariávelDefeitoDescrição
SIGA_GATEWAY_FAILURE_RATE_ALERT_SLACK_URLfallback SIGA_GATEWAY_ALERT_SLACK_URLSlack Incoming Webhook
SIGA_GATEWAY_FAILURE_RATE_ALERT_EMAIL_TODestinatários (Resend)
SIGA_GATEWAY_FAILURE_RATE_THRESHOLD0.25Limiar 0–1
SIGA_GATEWAY_FAILURE_RATE_MIN_EVENTS5Mínimo de eventos antes de alertar
SIGA_GATEWAY_FAILURE_RATE_COOLDOWN_HOURS6Evita spam (registo em saas_audit_logs)
  • Automático: após cada falha de webhook, o servidor verifica a taxa (se alertas configurados).
  • Cron: npm run siga:gateway-failure-rate-check (sugerido de hora a hora).
  • GitHub Actions: workflow gateway-failure-rate-check.yml (mesmos secrets, skip se Supabase em falta).

Modelo para pedir credenciais ao banco: Pedido ao banco EMIS/Unitel.

Logs estruturados

Procurar no stdout do servidor:

json
{"tag":"gateway-webhook","ok":false,"status":401,"channel":"multicaixa_express",}

Referências são mascaradas nos logs e na BD (últimos 4 dígitos). A API key nunca é persistida.

Verificação pós-correcção

  • [ ] Simulador ou webhook de teste → HTTP 200, planSettled: true
  • [ ] Fatura de teste nova → pagamento real ou simulado → paid
  • [ ] Recibo visível na tesouraria
  • [ ] Escola documentou URL + API key no portal banco

Prevenção

  • Seguir Checklist de produção antes do go-live.
  • Não partilhar API keys entre escolas.
  • Após mudança de hostname (domínio custom), actualizar URL no portal banco.
  • CI nocturno @live alerta regressões (gateway-live.spec.ts).

Ver também

WEB vende · ADMIN controla · SIGA trabalha · DOC explica