Aparência
Checklist de produção — EMIS e Unitel
Guia para operadores SIGA Plus e administradores escolares activarem pagamentos automáticos com credenciais reais nos portais EMIS/Multicaixa e Unitel Money.
O SIGA não emite credenciais bancárias. A escola obtém merchant/entidade junto do banco ou operador; o SIGA recebe o webhook e liquida a fatura.
Papéis
| Papel | Responsabilidade |
|---|---|
| Operador plataforma | Hostname público activo, TLS, escola visível no ADMIN |
| Administrador escolar | Integrações, entidade EMIS, teste de fatura |
| Tesouraria / banco | Contrato EMIS, URL de callback no portal externo |
Fase 1 — Pré-requisitos SIGA
- [ ] Escola provisionada (WEB
/startou ADMIN) com subscrição activa - [ ] Hostname público acessível (ex.
escola.portal-siga.comou domínio custom activo em ADMIN/domains) - [ ] Plano financeiro activo (bootstrap ou Definições → Financeiro)
- [ ] Pelo menos uma fatura de teste emitida em
/faturas(estadoopen)
Fase 2 — Configurar no SIGA
- Definições → Integrações
- Instalar Multicaixa Express e/ou Unitel Money
- Copiar da secção «Webhook de confirmação»:
- URL (EMIS ou Unitel — são diferentes)
- API key (
webhookApiKey)
- Multicaixa: preencher Merchant EMIS / Multicaixa (4–6 dígitos) — valor atribuído pelo banco, não
99824(demo) - Guardar integração com estado
connectedouconfigured
| Canal | URL de callback (substituir hostname) |
|---|---|
| EMIS / Multicaixa | https://{hostname}/api/finance/gateway/confirm |
| Unitel Money | https://{hostname}/api/finance/gateway/unitel/confirm |
Corpo JSON que o portal externo deve enviar:
json
{
"apiKey": "<webhookApiKey copiada do SIGA>",
"reference": "123456789",
"amount": 45000,
"invoiceId": "<uuid da fatura, recomendado>"
}Fase 3 — Portal EMIS / Multicaixa (externo)
Passos típicos no portal do banco/EMIS (nomes variam por instituição):
- [ ] Contrato merchant activo para a escola
- [ ] Entidade EMIS registada — mesmo valor que no SIGA (Integrações → Merchant EMIS)
- [ ] URL de notificação =
https://{hostname}/api/finance/gateway/confirm - [ ] Método
POST, corpo JSON - [ ] Campo de autenticação =
apiKeyno JSON (valor do SIGA, não o merchant ID) - [ ] Montante em kwanzas inteiros, referência de 9 dígitos sem espaços
Fase 4 — Portal Unitel Money (externo)
- [ ] Conta merchant Unitel activa
- [ ] URL de callback =
https://{hostname}/api/finance/gateway/unitel/confirm(não a rota Multicaixa) - [ ] Mesmo corpo JSON (
apiKey,reference,amount,invoiceId?) - [ ] API key = valor de Integrações → Unitel Money (integração separada da Multicaixa)
Fase 5 — Go-live (validação)
5.1 Referência visível
- [ ] Em
/faturas, abrir fatura de teste → Referência EMIS /PaymentReferenceCardmostra entidade + referência - [ ] Plano em estado
pending_gateway(tesouraria ou emissão com canal gateway)
5.2 Simulador (ambiente de staging / dev)
Com SIGA a correr e .env com SIGA_GATEWAY_DEV_API_KEY:
sh
# EMIS
npm run siga:gateway-simulate -- --invoice-id=<uuid> [--amount=45000]
# Unitel (mesma fatura, URL dedicada)
npm run siga:gateway-simulate -- --invoice-id=<uuid> --unitelResposta esperada: HTTP 200, { "ok": true, "planSettled": true }.
5.3 Pagamento real (produção)
- [ ] Pagamento no terminal/app com a referência exacta da fatura
- [ ] Webhook recebido pelo SIGA (ver logs do servidor ou estado da fatura →
paid) - [ ] Recibo gerado; plano
settled - [ ] Se falhar: confirmar manualmente via
PaymentReferenceCardna fatura (fallback)
5.4 CI @live (equipa SIGA Plus)
Com Supabase de staging:
sh
SIGA_E2E_LIVE=1 npm run siga:e2e-playwright-liveInclui gateway-live.spec.ts — EMIS + Unitel, dev key e webhook por escola.
Fase 6 — Observabilidade pós-go-live
- [ ] Tabela
finance_gateway_webhook_eventsaplicada (npm run siga:sql) - [ ] Tesouraria vê últimos webhooks em Definições → Integrações
- [ ] Operador: ADMIN → Webhooks gateway (
/gateway-webhooks) - [ ] CLI:
npm run siga:gateway-events-recent -- --failures-only - [ ] Alertas opcionais no
.env:SIGA_GATEWAY_ALERT_SLACK_URL— cada falha HTTP ≥ 400SIGA_GATEWAY_FAILURE_RATE_*— taxa 24h elevada (Slack/Resend)
- [ ] Cron sugerido:
npm run siga:gateway-failure-rate-check(horário) - [ ] GitHub Actions nocturno: workflow
gateway-failure-rate-check.yml(secrets opcionais)
Ver Runbook § Observabilidade e Pedido ao banco.
Erros frequentes em produção
| Sintoma | Causa provável | Acção |
|---|---|---|
401 API key inválida | Merchant ID colado no portal em vez de webhookApiKey | Copiar API key de Integrações |
| Referência não encontrada | Plano não está pending_gateway ou referência diferente | Reemitir referência; comparar 9 dígitos |
| Unitel não liquida | URL /gateway/confirm em vez de /unitel/confirm | Corrigir no portal Unitel |
| Entidade errada no ATM | Campo Merchant EMIS vazio ou demo 99824 | Preencher entidade real da escola |
| Webhook OK mas sem recibo | Permissões SGA / RPC register_payment | Aplicar SQL SGA; confirmar manualmente na tesouraria |
Segurança
- Não partilhar
webhookApiKeyentre escolas (multi-tenant) - Rotacionar API key se exposta — Definições → Integrações → Rotacionar key (Multicaixa/Unitel)
- A rotação gera key nova e mantém a anterior 24 horas (período de graça) — actualize o portal banco nesse intervalo
- Usar sempre HTTPS no hostname público
- Não commitar
.envnem chaves no repositório