1. Manual de Integração ERP — Portal Retail API
1. Visão Geral
1.1 Objetivo do Módulo ERP
O módulo ERP da API Portal Retail foi desenvolvido para permitir que sistemas ERP externos sincronizem seus dados com a plataforma de forma segura, confiável e em larga escala. O sistema funciona como intermediário entre seu ERP e a plataforma Portal Retail, processando informações sobre produtos, estoque, vendas, lojas e fornecedores.
Finalidade principal:
- Importar dados de produtos com todos os atributos (NCM, códigos, dimensões, etc.)
- Sincronizar informações de estoque em tempo real
- Registrar vendas diárias e mensais
- Gerenciar dados de lojas, fornecedores e grupos de compra
- Manter histórico completo de integrações com rastreamento de sucesso/falha
1.2 Como Funciona o Fluxo de Integração
O fluxo de integração ocorre em três etapas:
Etapa 1: Autenticação
Sua empresa envia uma requisição HTTP com a chave de acesso (API Key) no cabeçalho:
X-API-Key: SUA-CHAVE-DE-ACESSO-AQUI
Etapa 2: Envio de Dados
Você envia os dados em formato JSON, identificando o tipo de operação:
- Criação individual: Um produto por vez
- Criação em lote: Até 1.000 produtos simultaneamente
- Atualização individual: Atualiza um registro
- Atualização em lote: Atualiza até 1.000 registros
Etapa 3: Processamento e Resposta
A API processa os dados e retorna um de dois resultados:
Processamento imediato:
- Sucesso: HTTP 200 (sem lote) ou 201 (criação individual)
- Falha: HTTP 400 com detalhes do erro
Processamento assíncrono (para lotes):
- HTTP 202 Accepted
- Você recebe um ID de trabalho
- Consulta o status posteriormente usando este ID
1.3 Operações Síncronas vs Assíncronas
A API diferencia dois modos de processamento:
Operações Síncronas (Resposta Imediata)
-
GET /latest-integration — Obtém a data da última sincronização
-
Retorno: 200 OK com dados
-
Tempo: < 1 segundo
-
POST /endpoint (individual) — Cria um registro isolado
-
Retorno: 201 Created ou 400 Bad Request
- Tempo: 1-5 segundos
-
Usar para: Operações urgentes ou testes
-
PUT /endpoint (individual) — Atualiza um registro isolado
- Retorno: 200 OK ou 400 Bad Request
- Tempo: 1-5 segundos
Operações Assíncronas (Processamento em Background)
-
POST /endpoint/batch — Enfileira múltiplos registros
-
Retorno: 202 Accepted + jobId
- Processamento: Em background (até 5 minutos dependendo do volume)
-
Usar para: Grandes volumes, sincronizações periódicas
-
PUT /endpoint/batch — Atualiza múltiplos registros
- Retorno: 202 Accepted + jobId
- Processamento: Em background
Monitoramento de Batch
- GET /batch-job-report/{jobId} — Consulta status do processamento
- Retorno: 200 OK com progresso completo
- Atualizado em tempo real
- Mostra: Itens processados, erros, status final
1.4 Entendendo HTTP 202 Accepted
O código HTTP 202 é crucial para entender como a API ERP funciona. Diferente do 201 (Created) que indica conclusão imediata:
O que significa 202 Accepted?
202 Accepted significa:
✓ Sua requisição foi recebida e VALIDADA
✓ Seu trabalho foi ENFILEIRADO com sucesso
✗ Mas NÃO foi PROCESSADO ainda
Fluxo Completo (Exemplo: 100 Produtos)
| Tempo | Evento | Status |
|---|---|---|
| 00:00 | Você envia POST batch com 100 produtos | --- |
| 00:01 | API retorna 202 + jobId | Enfileirado |
| 00:02 | Sistema começa a processar em background | Processando |
| 00:05 | Sistema termina: 100 sucesso, 0 erro | Finished |
| 00:06 | Você consulta GET /batch-job-report/jobId | Concluído ✓ |
A Diferença: 201 vs 202
HTTP 201 Created (operação individual)
POST /erp-data/product
Body: { produto }
↓
Processamento: IMEDIATO (1-5 segundos)
↓
Resposta: 201 Created
{
"id": 12345,
"description": "Dipirona 500mg",
"message": "Produto criado com sucesso"
}
HTTP 202 Accepted (operação em lote)
POST /erp-data/product/batch
Body: { produtos: [100 itens] }
↓
Validação: IMEDIATA (< 1 segundo)
↓
Resposta: 202 Accepted
{
"jobId": "hangfire-job-12345",
"message": "Batch received and will be processed asynchronously",
"totalItems": 100
}
↓
Processamento: EM BACKGROUND (até 5 minutos)
↓
Consulte: GET /batch-job-report/hangfire-job-12345
O que NÃO fazer com 202
❌ Não assuma que os dados foram salvos ❌ Não use o ID retornado imediatamente ❌ Não espere em polling infinito ❌ Não reenvie se receber 202
O que FAZER com 202
✅ Armazene o jobId ✅ Consulte o status a cada 10-30 segundos ✅ Continue seu fluxo normal enquanto processa ✅ Implemente um timeout (ex: após 5 minutos, considere falha)
1.5 Estados de Processamento de Batch
Quando você consulta GET /batch-job-report/{jobId}, o sistema retorna o estado atual do trabalho:
| Estado | Significado | Deve Reenviar? |
|---|---|---|
| Enqueued | Aguardando processamento na fila | Não |
| Processing | Processando ativamente | Não |
| Finished | Concluído com sucesso | Verifique erros |
| Failed | Falha total (erro no sistema) | Sim, após corrigir |
Exemplo de Resposta - Estado Finished
{
"jobId": "hangfire-job-12345",
"entityType": "ErpProduct",
"state": "Finished",
"isComplete": true,
"createdAt": "2024-12-06T10:30:00Z",
"startedAt": "2024-12-06T10:30:02Z",
"completedAt": "2024-12-06T10:35:15Z",
"duration": "00:05:13",
"totalItems": 100,
"successCount": 100,
"failureCount": 0,
"retryAttempt": 0,
"hasPartialData": false,
"errorMessage": null,
"exceptionDetails": null
}
Interpretação:
state: "Finished"— Processamento concluídosuccessCount: 100— Todos os 100 itens foram aceitosfailureCount: 0— Nenhuma falhaerrorMessage: null— Sem erros gerais- Resultado final: SUCESSO TOTAL ✓
Exemplo de Resposta - Estado Finished com Erros Parciais
{
"jobId": "hangfire-job-12346",
"entityType": "ErpProduct",
"state": "Finished",
"isComplete": true,
"totalItems": 100,
"successCount": 95,
"failureCount": 5,
"hasPartialData": true,
"errorMessage": "5 items failed validation",
"exceptionDetails": null
}
Interpretação:
state: "Finished"— Processamento concluídosuccessCount: 95— 95 itens foram salvosfailureCount: 5— 5 itens falharamhasPartialData: true— Dados parcialmente processados- Resultado final: SUCESSO PARCIAL ⚠️ — Investigue os 5 erros
Exemplo de Resposta - Estado Failed
{
"jobId": "hangfire-job-12347",
"entityType": "ErpProduct",
"state": "Failed",
"isComplete": true,
"totalItems": 100,
"successCount": 0,
"failureCount": 100,
"retryAttempt": 5,
"hasPartialData": false,
"errorMessage": "Database connection lost",
"exceptionDetails": "ConnectionPool exhausted after 5 retry attempts"
}
Interpretação:
state: "Failed"— Falha completasuccessCount: 0— Nenhum item foi salvoretryAttempt: 5— Sistema tentou 5 vezeserrorMessage— Motivo da falha (problema do servidor, não dos dados)- Resultado final: FALHA DO SISTEMA — Aguarde 5 minutos e reenvie
1.6 Estratégia de Logging Condicional
A API implementa um sistema inteligente de logging para reduzir ruído e evitar duplicação de registros no banco de dados:
Para operações individuais (POST/PUT não-batch):
- ✅ Erros sempre registrados — Validação, conflitos, exceções
- ❌ Sucessos não registrados — Reduz ruído mantendo foco em problemas
- Resultado: Histórico limpo, fácil de auditar
Para operações em lote (POST/PUT batch):
- ✅ Um log agregado por batch — Contém resumo completo (total, sucessos, falhas)
- ❌ Nenhum log de itens individuais — Evita 1.000+ registros por batch
- Resultado: Rastreabilidade sem poluição de dados
Exemplo:
Cenário 1: POST /product (individual)
- Sucesso: NÃO aparece no histórico
- Erro: Aparece com detalhes
Cenário 2: POST /product/batch com 1.000 itens
- 950 sucessos + 50 erros
- Histórico: UM registro com resumo (950 ok, 50 falhado)
- NÃO: 1.000 registros individuais
Implicações para sua integração:
- ✓ Histórico de integração fica limpo e otimizado
- ✓ Erros são fáceis de identificar (aparecem no histórico)
- ⚠️ Sucessos individuais NÃO aparecem (implemente logging cliente se precisar)
- ✓ Status de batch sempre disponível via
/batch-job-report/{jobId}
Próximas Seções
Este manual está organizado conforme segue: