TL;DR
- Não exponhas SAP directamente ao portal. Usa uma camada de API ou BFF para controlar autenticação, autorização, rate limits, auditoria e transformação de dados.
- Se o portal é maioritariamente de leitura, cria um read model fora do SAP. Consultar SAP em tempo real para cada ecrã costuma rebentar latência, licenciamento e disponibilidade.
- OAuth2 ou SAML resolvem identidade, não resolvem autorização de negócio. Tens de mapear utilizadores externos para entidades SAP como customer number, sales org, company code e roles.
- SAP OData é útil para muitos cenários, mas não é uma arquitectura por si só. Cuidado com paginação, filtros caros, CSRF tokens, ETags e semântica de erros.
- A parte crítica não é o login. É impedir que um cliente veja encomendas, facturas, preços ou tickets de outro cliente, sobretudo em contas com grupos empresariais, delegações e utilizadores externos.
O problema real: um portal de cliente não é apenas um front-end sobre SAP
A pergunta parece simples: “como construo um portal de cliente seguro sobre dados SAP?” A resposta curta é: com uma fronteira muito clara entre o mundo externo e o ERP.
Um portal de cliente típico precisa de mostrar encomendas, facturas, notas de crédito, estado de entregas, contratos, preços, consumos, tickets ou documentação. Quase tudo isto vive, directa ou indirectamente, em SAP. O erro comum é tratar SAP como se fosse uma base de dados relacional normal e construir o portal a chamar serviços OData, RFC ou BAPI sempre que o utilizador abre uma página.
Isso funciona numa demo. Em produção, aparecem os problemas: p99 acima de 2 segundos, timeouts em horas de maior carga, queries que dependem de índices e customizing SAP, utilizadores externos que não encaixam no modelo de autorização interno, e equipas Basis pouco satisfeitas com tráfego imprevisível vindo da internet.
A minha opinião é simples: SAP deve ser a fonte de verdade para processos de negócio, mas não deve ser o runtime principal do teu portal. O portal precisa de uma camada própria, com contratos de API pensados para utilizadores externos, segurança aplicacional explícita e observabilidade independente.
A arquitectura de base costuma ter estes blocos:
- Portal web ou mobile.
- Identity provider externo, por exemplo Microsoft Entra ID, Auth0, Okta ou SAP Cloud Identity Services.
- Backend for Frontend ou API Gateway aplicacional.
- Camada de integração com SAP, por OData, RFC, IDoc, SOAP ou SAP Integration Suite.
- Read model fora do SAP, quando há volume, pesquisa ou necessidade de baixa latência.
- Auditoria e monitorização próprias.
O ponto mais importante: o portal nunca deve confiar apenas no que o front-end envia. O backend deve validar sempre quem é o utilizador, que conta representa, que permissões tem e que objectos SAP pode consultar ou alterar.
Escolher o padrão de integração: tempo real, réplica ou híbrido
Há três padrões realistas para expor dados SAP a clientes externos.
| Padrão | Quando usar | Vantagens | Riscos |
|---|---|---|---|
| Chamadas em tempo real a SAP | Dados críticos e pouco frequentes, como submissão de encomenda ou validação de crédito | Fonte de verdade imediata, menos duplicação | Latência alta, dependência directa de SAP, menor tolerância a falhas |
| Read model replicado | Listagens, histórico, facturas, encomendas, tracking, catálogos | p95 abaixo de 200 ms é viável, pesquisa rápida, menos carga em SAP | Consistência eventual, precisa de sincronização e reconciliação |
| Híbrido | A maioria dos portais B2B | Equilibra performance e exactidão | Exige desenho claro de quais dados são síncronos e quais são assíncronos |
Para um portal com 500 clientes activos e páginas de listagem, eu evitaria consultar SAP em tempo real para tudo. Uma listagem de facturas com filtros por data, estado e referência do cliente pode parecer banal, mas pode gerar muitas chamadas caras. Se cada utilizador fizer 20 interacções por sessão e cada interacção chamar SAP, 300 utilizadores simultâneos transformam-se facilmente em milhares de chamadas num curto intervalo.
Um read model em PostgreSQL 16, SQL Server ou Elasticsearch pode manter os dados necessários para leitura: cabeçalhos de factura, estado de encomenda, linhas resumidas, valores, moeda, datas e referências. SAP continua a ser a fonte de verdade. O portal apenas mantém uma projecção optimizada para consulta externa.
A sincronização pode vir de várias formas:
- SAP OData com polling incremental, se houver campos de alteração fiáveis.
- IDocs para eventos de negócio já existentes.
- Change pointers em SAP, quando aplicável.
- SAP Event Mesh, em arquitecturas mais modernas sobre SAP BTP.
- Jobs nocturnos para dados pouco sensíveis ao tempo, como documentos antigos.
- Integração por SAP Cloud Integration, quando há necessidade de orquestração e transformação.
A documentação oficial relevante depende da paisagem SAP, mas vale consultar SAP Gateway OData, SAP Cloud Connector, SAP Integration Suite e SAP Event Mesh. Para autenticação e autorização, OAuth 2.0 está definido na RFC 6749 e OpenID Connect Core 1.0 é a referência prática para identidade.
Segurança: identidade, autorização e isolamento de dados
Autenticar é saber quem entrou. Autorizar é saber o que essa pessoa pode fazer. Num portal sobre SAP, a segunda parte é onde estão os incidentes sérios.
Um token OIDC pode dizer que o utilizador é [email protected]. Isso não chega para mostrar facturas. O backend precisa de saber:
- A que customer numbers SAP essa pessoa está associada.
- Se pode ver dados da empresa toda ou apenas de uma delegação.
- Se pode consultar preços, facturas, contratos ou apenas encomendas.
- Se pode submeter pedidos que criam documentos em SAP.
- Se existe relação entre conta externa, sales organization, distribution channel e company code.
Uma forma prática é manter uma tabela de autorização externa, gerida pelo portal ou sincronizada de um sistema mestre. Essa tabela liga utilizadores e grupos externos a entidades SAP. Não uses o email como chave de autorização para dados SAP. Emails mudam, podem ser reutilizados e raramente modelam estruturas empresariais.
Um exemplo mínimo de claims úteis num token ou sessão interna:
{
"sub": "usr_12345",
"tenant_id": "customer_group_987",
"sap_customers": ["0001234567", "0001234568"],
"permissions": ["orders:read", "invoices:read", "tickets:create"],
"assurance_level": "mfa"
}
O detalhe dos zeros à esquerda não é cosmético. Em SAP, identificadores como KUNNR costumam ter padding. Já vi integrações falharem autorização porque a aplicação comparava 1234567 com 0001234567. O resultado pode ser falso negativo, que irrita utilizadores, ou pior, uma normalização mal feita que mistura entidades.
Também não basta esconder botões no front-end. Cada endpoint deve validar autorização ao nível do objecto. Por exemplo, GET /invoices/90000123 tem de verificar que a factura pertence a um customer number autorizado para aquele utilizador. Não confies no filtro da listagem anterior.
Regras mínimas que aplicaria:
- MFA obrigatório para utilizadores com acesso a facturas, preços ou dados pessoais.
- Sessões curtas para operações sensíveis, por exemplo reautenticação após 15 minutos para alteração de dados bancários.
- Rate limiting por utilizador, tenant e IP. Um ponto de partida razoável: 60 pedidos por minuto por utilizador e limites separados para endpoints caros.
- Auditoria imutável para visualização de documentos sensíveis e alterações.
- Encriptação em trânsito com TLS 1.2 no mínimo, preferencialmente TLS 1.3.
- Segredos em gestor próprio, como AWS Secrets Manager, Azure Key Vault, HashiCorp Vault ou SAP Credential Store.
- Separação de ambientes. Nunca uses dados reais de clientes em ambientes de desenvolvimento sem anonimização.
API e BFF: a fronteira que protege SAP
A camada intermédia não deve ser um proxy passivo. Deve traduzir o modelo SAP para contratos de produto estáveis.
SAP tem objectos e estruturas pensadas para processos internos. O portal precisa de APIs orientadas a casos de uso: “listar facturas do cliente”, “obter estado da encomenda”, “submeter pedido de devolução”, “descarregar documento PDF”. Se expões directamente entidades OData internas ao browser, estás a acoplar o produto ao customizing SAP e a aumentar a superfície de ataque.
Duas alternativas comuns:
| Opção | Prós | Contras |
|---|---|---|
| SAP BTP com SAP API Management e Integration Suite | Boa integração com ecossistema SAP, Cloud Connector, políticas de API, principal propagation | Pode ficar caro e complexo, exige competências SAP BTP, risco de lógica de produto ficar espalhada |
| Backend próprio em Node.js 22 LTS.NET 8 ou Java 21 | Controlo total sobre UX, autorização, caching, testes e observabilidade | Tens de gerir operação, segurança e conectores com disciplina |
A escolha não é religiosa. Se a organização já usa SAP BTP bem, faz sentido aproveitar SAP API Management, Cloud Integration e Cloud Connector. Se o portal é um produto digital com muitas regras de UX, onboarding, permissões e integrações não SAP, costumo preferir um backend próprio, mesmo que use BTP para a conectividade segura ao SAP.
O que não gosto: browser a chamar SAP Gateway directamente. Mesmo com OAuth2, estás a colocar demasiada superfície SAP no exterior. Prefiro que SAP Gateway fique acessível apenas a partir da rede controlada ou via SAP Cloud Connector, e que o portal fale com uma API desenhada para ele.
Contratos de API devem incluir:
- Paginação cursor based quando possível, não apenas
offset. - ETags ou versões para evitar actualizações perdidas.
- Erros normalizados, com códigos aplicacionais claros.
- Idempotency keys para operações que criam pedidos, encomendas ou pagamentos.
- Timeouts curtos. Por exemplo, 3 segundos para leitura síncrona e 10 segundos para operações críticas raras.
- Correlation ID propagado do portal até SAP, logs e filas.
Dados, cache e consistência: onde muitos portais ficam lentos
Um portal de cliente seguro também tem de ser previsível. Segurança sem disponibilidade não serve o negócio. A pergunta principal é: que dados têm de estar absolutamente actuais?
Nem tudo precisa do mesmo nível de frescura:
| Tipo de dado | Frescura aceitável | Estratégia recomendada |
|---|---|---|
| Estado de encomenda | 1 a 15 minutos | Read model com sincronização incremental |
| Facturas emitidas | 15 minutos a algumas horas | Replicação e reconciliação diária |
| Preços personalizados | Depende do contrato | Consulta controlada a SAP ou cache curta |
| Limite de crédito | Segundos a minutos | Tempo real ou cache muito curta |
| Submissão de encomenda | Imediato | Chamada síncrona ou fila com confirmação clara |
| PDFs legais | Depende da emissão | Armazenamento seguro com URLs temporários |
Se usares cache, sê explícito sobre invalidation. Caches genéricas de 30 minutos podem criar problemas legais ou comerciais se mostrarem preços errados, estado de pagamento desactualizado ou documentos revogados. Para dados sensíveis, prefiro cache por tenant e por permissão, com chaves que incluam o contexto de autorização.
Outro ponto crítico é pesquisa. SAP não é o sítio ideal para pesquisa livre por referência, texto, intervalo de datas, estado e número de encomenda do cliente. Para isso, PostgreSQL com índices adequados pode chegar perfeitamente. Elasticsearch ou OpenSearch fazem sentido quando há pesquisa textual pesada ou volumes maiores. Não metas Elasticsearch só porque parece moderno. Para 10 GB de dados de portal e filtros estruturados, PostgreSQL 16 bem indexado é muitas vezes suficiente.
Para sincronização, desenha sempre reconciliação. Eventos perdem-se, jobs falham, IDocs ficam presos, e alguém altera customizing. Um processo diário que compara contagens e checksums por período pode poupar dias de investigação. Não precisa de ser sofisticado no início. Precisa de existir.
Operações sensíveis: escrita em SAP sem criar duplicados
Ler dados é metade do problema. A outra metade é permitir que clientes façam acções: criar pedido de assistência, submeter encomenda, actualizar morada, pedir segunda via, aceitar orçamento ou iniciar devolução.
Aqui entram três regras.
Primeira: operações que alteram SAP devem ser idempotentes. Se o utilizador carrega duas vezes no botão, se o browser repete o pedido ou se há timeout entre o backend e SAP, não podes criar duas encomendas.
Segunda: a confirmação ao utilizador tem de reflectir a realidade. Se a operação ficou em fila, diz “pedido recebido” e mostra um estado pendente. Não digas “encomenda criada” antes de teres o número SAP.
Terceira: validações de negócio críticas devem ficar perto da fonte de verdade. O portal pode validar formato, campos obrigatórios e permissões. Mas crédito, disponibilidade final, bloqueios de cliente e regras fiscais devem ser confirmados por SAP ou por um serviço autorizado.
Um padrão que funciona bem:
- Portal envia pedido com idempotency key.
- Backend valida identidade, autorização e schema.
- Pedido é persistido com estado
received. - Worker processa a criação em SAP.
- Resultado guarda número SAP, mensagens e estado final.
- Portal consulta estado por API ou recebe notificação.
Para operações que têm de ser síncronas, define timeouts e compensação. Se SAP não responde em 10 segundos, o portal deve guardar o pedido e continuar de forma assíncrona, ou então falhar com mensagem honesta. O pior cenário é o utilizador não saber se criou ou não criou o documento.
Observabilidade, auditoria e gotchas de produção
Um portal sobre SAP falha de formas pouco óbvias. Por isso, instrumentação não é opcional.
Métricas mínimas:
- Latência p50, p95 e p99 por endpoint.
- Taxa de erro por integração SAP, separando 4xx, 5xx, timeouts e erros de negócio.
- Número de chamadas SAP por utilizador e por tenant.
- Tamanho e idade das filas.
- Lag de sincronização por entidade, por exemplo encomendas 4 minutos, facturas 32 minutos.
- Cache hit ratio por tipo de dado.
- Tentativas de acesso negado a objectos.
Logs devem incluir correlation ID, tenant, utilizador interno do portal, objecto de negócio e resultado. Não devem incluir dados pessoais desnecessários, tokens, passwords, cookies ou PDFs em base64.
Auditoria é diferente de logging. Auditoria responde a perguntas como: “quem viu esta factura?”, “quem descarregou este documento?”, “quem alterou a morada de entrega?”, “que utilizador externo submeteu este pedido?”. Deve ser difícil de alterar e ter política de retenção clara. Em sectores regulados ou com dados pessoais, alinha isto com RGPD e com as equipas legais.
Gotchas que merecem atenção:
- CSRF em SAP OData. Muitas operações de escrita exigem token CSRF obtido antes. Ignorar isto gera erros intermitentes e más soluções de retry.
- Timezones e datas SAP. Uma data de entrega sem timezone não é o mesmo que timestamp UTC. Define semântica por campo.
- Autorização por hierarquia empresarial. Um grupo pode ter várias contas SAP, mas nem todos os utilizadores podem ver todas.
- Paginação com
$skipem datasets grandes. Pode ficar lenta e inconsistente. Prefere cursores ou replicação. - Mensagens SAP não são UX. Códigos e textos técnicos devem ser traduzidos para mensagens úteis, mantendo detalhe nos logs.
- Ambientes SAP não são iguais. DEV, QA e PRD podem ter customizing, dados e autorizações diferentes. Testes só em DEV não provam muito.
Conclusão
Construir um portal de cliente seguro sobre SAP é menos sobre “ligar uma API” e mais sobre desenhar uma fronteira fiável entre clientes externos e processos internos. A arquitectura certa separa identidade, autorização, integração, read models, auditoria e operação. O SAP continua a mandar nos processos críticos, mas o portal não pode ficar refém da latência e do modelo interno do ERP.
Se estás a enfrentar um problema parecido, marca uma conversa em https://impact-origin.com/agendamento.