Webhook para Notificação de Eventos
Visão Geral
O webhook é utilizado para notificar seu sistema sobre eventos transacionais ocorrendo na base Grocers envolvendo o catálogo e os pedidos. O sistema implementa um mecanismo robusto de notificações com suporte a retry, autenticação e tratamento de erros.
Limitações
- Um webhook por ContractAccountId: Cada conta pode ter apenas uma configuração de webhook ativa
- Timeout de 30 segundos: Notificações que não recebem resposta em 30 segundos são consideradas falhas
- Máximo de 3 retentativas: Em caso de falha, o sistema tenta reenviar até 3 vezes
Endpoint de Configuração
Rota: POST /v1/webhooks
Solicitação de Configuração
Para criar uma assinatura de webhook, envie uma solicitação POST para o endpoint /v1/webhooks com o seguinte formato:
{
"originType": "Api_call",
"originData": "ProductUpdate",
"url": "https://api.seusite.com/webhooks/grocers",
"authType": "Bearer",
"authToken": "seu-token-secreto",
"eventTypes": [
"Product_Created",
"Product_Updated",
"Product_CreationFailed",
"Product_UpdateFailed",
"Order_Updated",
"Order_UpdateFailed"
]
}
IMPORTANTE: Para receber notificações de erro, você deve explicitamente incluir os tipos de eventos de erro (como
Product_CreationFailed) na lista deeventTypes. Sem essa configuração, você não receberá webhooks quando ocorrerem falhas nas operações.
Campos da Solicitação
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| originType | enum | Sim | Tipo de origem (User = 1, Api_call = 2) |
| originData | string | Sim | Identificador da origem |
| url | string | Sim | URL que receberá as notificações (HTTPS obrigatório) |
| authType | string | Não | Tipo de autenticação (Bearer, Basic, Custom) |
| authToken | string | Não | Token de autenticação |
| eventTypes | array | Sim | Lista de tipos de eventos para assinar |
Notificações
Formato da Notificação
Todas as notificações são enviadas como POST HTTP com o seguinte formato:
{
"operationId": "54d6a979-5f62-4e17-9d4c-dbd9f5ede403",
"relatedEntity": "Product",
"eventType": 1,
"data": {
"externalReference": "prod-123",
"name": "Produto Exemplo",
"description": "Descrição do produto",
"status": "active"
},
"contractAccountId": "9f36a666-acd5-4987-a47f-3de247f65d82"
}
Campos da Notificação
| Campo | Tipo | Descrição |
|---|---|---|
| operationId | string | Identificador único da operação |
| relatedEntity | string | Entidade relacionada ao evento |
| eventType | number | Tipo do evento |
| data | object | Dados específicos do evento |
| contractAccountId | string | Identificador da conta |
| error | object | Presente apenas em caso de erro |
Tipos de Eventos
1. Produtos
Eventos de Sucesso:
- Product_Created = 1: Produto criado com sucesso
- Product_Updated = 2: Produto atualizado com sucesso
- Product_Deleted = 3: Produto deletado com sucesso
Eventos de Erro:
- Product_CreationFailed = 100: Falha na criação do produto
- Product_UpdateFailed = 110: Falha na atualização do produto
- Product_DeletionFailed = 120: Falha na deleção do produto
2. SKUs
Eventos de Sucesso:
- SKU_Created = 4: SKU criado com sucesso
- SKU_Updated = 5: SKU atualizado com sucesso
- SKU_Deleted = 6: SKU deletado com sucesso
Eventos de Erro:
- SKU_CreationFailed = 101: Falha na criação do SKU
- SKU_UpdateFailed = 111: Falha na atualização do SKU
- SKU_DeletionFailed = 121: Falha na deleção do SKU
3. Marcas
Eventos de Sucesso:
- Brand_Created = 7: Marca criada com sucesso
- Brand_Updated = 8: Marca atualizada com sucesso
- Brand_Deleted = 9: Marca deletada com sucesso
Eventos de Erro:
- Brand_CreationFailed = 102: Falha na criação da marca
- Brand_UpdateFailed = 112: Falha na atualização da marca
- Brand_DeletionFailed = 122: Falha na deleção da marca
4. Categorias
Eventos de Sucesso:
- Category_Created = 10: Categoria criada com sucesso
- Category_Updated = 11: Categoria atualizada com sucesso
- Category_Deleted = 12: Categoria deletada com sucesso
Eventos de Erro:
- Category_CreationFailed = 103: Falha na criação da categoria
- Category_UpdateFailed = 113: Falha na atualização da categoria
- Category_DeletionFailed = 123: Falha na deleção da categoria
5. Pedidos
Eventos de Sucesso:
- Order_Created = 13: Pedido criado com sucesso
- Order_Updated = 14: Pedido atualizado com sucesso
- Order_Deleted = 15: Pedido deletado com sucesso
- Order_StatusUpdated = 25: Status do pedido atualizado com sucesso
Eventos de Erro:
- Order_CreationFailed = 104: Falha na criação do pedido
- Order_UpdateFailed = 114: Falha na atualização do pedido
- Order_DeletionFailed = 124: Falha na deleção do pedido
- Order_StatusUpdateFailed = 118: Falha na atualização do status do pedido
6. Preços
Eventos de Sucesso:
- SKUPricing_Created = 16: Preço de SKU criado com sucesso
- SKUPricing_Updated = 17: Preço de SKU atualizado com sucesso
- SKUPricing_Deleted = 18: Preço de SKU deletado com sucesso
Eventos de Erro:
- SKUPricing_CreationFailed = 105: Falha na criação do preço
- SKUPricing_UpdateFailed = 115: Falha na atualização do preço
- SKUPricing_DeletionFailed = 125: Falha na deleção do preço
7. Estoque
Eventos de Sucesso:
- Warehouse_Created = 19: Estoque criado com sucesso
- Warehouse_Updated = 20: Estoque atualizado com sucesso
- Warehouse_Deleted = 21: Estoque deletado com sucesso
Eventos de Erro:
- Warehouse_CreationFailed = 106: Falha na criação do estoque
- Warehouse_UpdateFailed = 116: Falha na atualização do estoque
- Warehouse_DeletionFailed = 126: Falha na deleção do estoque
8. Estoque de SKU
Eventos de Sucesso:
- WarehouseSKU_Created = 22: Estoque de SKU criado com sucesso
- WarehouseSKU_Updated = 23: Estoque de SKU atualizado com sucesso
- WarehouseSKU_Deleted = 24: Estoque de SKU deletado com sucesso
Eventos de Erro:
- WarehouseSKU_CreationFailed = 107: Falha na criação do estoque de SKU
- WarehouseSKU_UpdateFailed = 117: Falha na atualização do estoque de SKU
- WarehouseSKU_DeletionFailed = 127: Falha na deleção do estoque de SKU
9. Erro Genérico
- Operation_Failed = 999: Falha genérica na operação
Exemplos de Payload por Entidade
Produto - Criação Bem-sucedida
{
"operationId": "54d6a979-5f62-4e17-9d4c-dbd9f5ede403",
"relatedEntity": "Product",
"eventType": 1,
"data": {
"externalReference": "103928",
"name": "Granola Tradicional com Castanhas Mãe Terra 800g",
"similarTerms": "granola,castanhas,mãe terra",
"slug": "granola-tradicional-castanhas-mae-terra-800g",
"title": "Granola Tradicional com Castanhas Mãe Terra 800g",
"shortDescription": "Granola Tradicional com Castanhas Mãe Terra 800g",
"longDescription": "Granola Tradicional com Castanhas Mãe Terra 800g",
"brandId": "e7b8a9d4-3f4b-4c8e-9d2e-1f5a6b7c8d9e",
"categoryId": "c9b1d5e4-2f3a-4b8e-9d1e-7f6a8b9c0d1f",
"commercialPoliticId": "b6a2f813-9952-4f35-fbc5-08dcf2bc3756",
"displayInSite": true,
"displayInSoldOut": false,
"fiscalCode": "11111",
"EAN": "7891150075443",
"punctuation": 1
},
"contractAccountId": "E9A2FCA6-198F-4B4A-A183-2356EF6562F5"
}
SKU - Criação Bem-sucedida
{
"operationId": "54d6a979-5f62-4e17-9d4c-dbd9f5ede403",
"relatedEntity": "SKU",
"eventType": 4,
"data": {
"externalReference": "103928",
"productExternalReference": "103928",
"name": "Granola Tradicional com Castanhas Mãe Terra 800g",
"EAN": "7891150075443",
"reference": "103928",
"weightForFreight": 1.0,
"heightForFreight": 1.0,
"widthForFreight": 1.0,
"lengthForFreight": 1.0,
"weightReal": 1.0,
"heightReal": 1.0,
"widthReal": 1.0,
"lengthReal": 1.0,
"arrivalDate": "2024-10-22",
"unitOfMeasurement": 1,
"unitMultiplier": 1.0,
"manufacturerCode": "103928"
},
"contractAccountId": "E9A2FCA6-198F-4B4A-A183-2356EF6562F5"
}
Produto - Falha na Criação
{
"operationId": "bb067d1e-5388-4794-95cb-188b417dc280",
"relatedEntity": "Product",
"eventType": 100,
"data": {
"name": "",
"similarTerms": null,
"slug": "",
"title": null,
"shortDescription": "Granola Tradicional com Castanhas Mãe Terra 800g",
"longDescription": "Granola Tradicional com Castanhas Mãe Terra 800g",
"brandId": "00000000-0000-0000-0000-000000000000",
"categoryId": "00000000-0000-0000-0000-000000000000",
"commercialPoliticId": "b6a2f813-9952-4f35-fbc5-08dcf2bc3756",
"displayInSite": true,
"displayInSoldOut": false,
"fiscalCode": "11111",
"EAN": "7891150075443",
"punctuation": 1,
"categoryExternalReference": "MAT/DOCES, COMP/DIET",
"brandExternalReference": "MÃE TERRA",
"externalReference": "103928"
},
"contractAccountId": "E9A2FCA6-198F-4B4A-A183-2356EF6562F5",
"error": {
"statusCode": 400,
"message": "Erro de validação",
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Erro de validação",
"detail": "Um ou mais produtos contêm dados inválidos",
"instance": "/v1/batch/products",
"traceId": "00-42bf4652eeb9c657161c4d7e92ec7cd7-27a5fd389fba4dbf-00",
"validationErrors": [
{ "id": 1, "validation": "Nome é um campo obrigatório", "key": "Name" },
{ "id": 2, "validation": "Título é um campo obrigatório", "key": "Title" },
{ "id": 3, "validation": "Slug é um campo obrigatório", "key": "Slug" }
]
}
}
Pedido - Atualização de Status
{
"operationId": "54d6a979-5f62-4e17-9d4c-dbd9f5ede403",
"relatedEntity": "Order",
"eventType": 25,
"data": {
"id": "order-123",
"status": 5,
"previousStatus": 4,
"updatedAt": "2024-02-04T12:30:00Z",
"externalReference": "ext-order-123"
},
"contractAccountId": "E9A2FCA6-198F-4B4A-A183-2356EF6562F5"
}
Tratamento de Erros
Política de Retry
- Primeira tentativa: Imediata
- Segunda tentativa: Após 1 minuto
- Terceira tentativa: Após 5 minutos
Formato de Erro Estruturado
Os webhooks de erro incluem informações detalhadas e estruturadas sobre o problema ocorrido. O campo eventType será alterado para o código de erro correspondente (por exemplo, Product_CreationFailed = 100 em vez de Product_Created = 1).
Exemplo de Erro de Limite de Caracteres
{
"operationId": "cc178e2f-6499-5805-a6de-299c528ed391",
"relatedEntity": "Product",
"eventType": 100,
"data": {
"name": "Nome muito longo que excede o limite de 120 caracteres permitidos pelo sistema de validação implementado para garantir a integridade dos dados",
"title": "Título muito longo que excede o limite de 60 caracteres permitidos",
"slug": "slug-muito-longo-que-excede-o-limite-de-120-caracteres-permitidos-pelo-sistema-de-validacao-implementado-para-garantir-integridade",
"externalReference": "103928"
},
"contractAccountId": "E9A2FCA6-198F-4B4A-A183-2356EF6562F5",
"error": {
"statusCode": 400,
"message": "Erro de validação",
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Erro de validação",
"detail": "Um ou mais produtos contêm dados inválidos",
"instance": "/v1/batch/products",
"traceId": "00-42bf4652eeb9c657161c4d7e92ec7cd7-27a5fd389fba4dbf-00",
"validationErrors": [
{ "id": 1, "validation": "Nome deve ter no máximo 120 caracteres", "key": "Name" },
{ "id": 2, "validation": "Título deve ter no máximo 60 caracteres", "key": "Title" },
{ "id": 3, "validation": "Slug deve ter no máximo 120 caracteres", "key": "Slug" }
]
}
}
Exemplo de Erro de SKU
{
"operationId": "dd289f3g-7500-6916-b7ef-400d639fe402",
"relatedEntity": "SKU",
"eventType": 101,
"data": {
"name": "Nome do SKU muito longo que excede o limite de 120 caracteres permitidos pelo sistema",
"EAN": "123456789012345678901234567890123",
"reference": "REF123456789012345678901234567890123",
"externalReference": "SKU-103928",
"productExternalReference": "103928"
},
"contractAccountId": "E9A2FCA6-198F-4B4A-A183-2356EF6562F5",
"error": {
"statusCode": 400,
"message": "Erro de validação",
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "Erro de validação",
"detail": "Um ou mais SKUs contêm dados inválidos",
"instance": "/v1/batch/products",
"traceId": "00-42bf4652eeb9c657161c4d7e92ec7cd7-27a5fd389fba4dbf-00",
"validationErrors": [
{ "id": 1, "validation": "Nome deve ter no máximo 120 caracteres", "key": "Name" },
{ "id": 2, "validation": "EAN deve ter no máximo 30 caracteres", "key": "EAN" },
{ "id": 3, "validation": "Reference deve ter no máximo 30 caracteres", "key": "Reference" }
]
}
}
Principais Melhorias Implementadas
- Validações Rigorosas: Sistema agora valida todos os limites de caracteres conforme banco de dados
- Mensagens Específicas: Erros detalhados indicando exatamente qual campo e limite foi violado
- Prevenção de Truncamento: Dados inválidos são rejeitados antes de causar erros 500
- Webhooks Corretos: Não há mais webhooks de sucesso para operações que falharam
- Rastreabilidade: TraceId permite correlacionar erros com logs internos
Estrutura do Objeto Error
| Campo | Tipo | Descrição |
|---|---|---|
| statusCode | number | Código de status HTTP do erro |
| message | string | Mensagem resumida do erro |
| type | string | URI que identifica o tipo de erro |
| title | string | Título do erro |
| detail | string | Descrição detalhada do erro |
| instance | string | URI que identifica a instância específica do erro |
| traceId | string | Identificador para rastreamento do erro |
| validationErrors | array | Lista de erros de validação específicos |
Estrutura do Objeto ValidationError
| Campo | Tipo | Descrição |
|---|---|---|
| id | number | Identificador numérico sequencial do erro |
| validation | string | Mensagem de erro de validação |
| key | string | Nome do campo com problema |
Importante: Assinatura de Eventos de Erro
Para receber notificações de erro, é necessário assinar explicitamente os tipos de eventos de erro correspondentes. Por exemplo, para receber erros de criação de produtos, você deve incluir Product_CreationFailed na lista de eventTypes ao configurar seu webhook.
Troubleshooting
Problemas Comuns
-
Webhook não recebe notificações
- Verificar se a URL está acessível
- Confirmar se o HTTPS está configurado corretamente
- Validar se o token de autenticação está correto
-
Erros de autenticação
- Verificar formato do token
- Confirmar se o token não expirou
- Validar configuração do authType
-
Timeout nas notificações
- Otimizar tempo de resposta do endpoint
- Implementar processamento assíncrono
- Considerar usar filas do lado do cliente
Boas Práticas
-
Segurança
- Use HTTPS
- Implemente validação do token
- Valide a origem das requisições
-
Performance
- Responda rapidamente (< 1s)
- Processe assincronamente
- Implemente filas se necessário
-
Resiliência
- Implemente idempotência
- Armazene notificações recebidas
- Mantenha logs detalhados
-
Monitoramento
- Monitore taxa de sucesso
- Acompanhe tempos de resposta
- Configure alertas para falhas
Boas Práticas para Tratamento de Erros
-
Assine Eventos de Erro
- Inclua explicitamente todos os eventos de erro relevantes na configuração do webhook
- Exemplo: se você assina
Product_Created, também assineProduct_CreationFailed
-
Processamento de Erros
- Implemente lógica para processar os diferentes tipos de erros
- Utilize o campo
validationErrorspara identificar problemas específicos - Crie mecanismos de correção automática quando possível
-
Registro e Análise
- Mantenha um registro detalhado de todos os erros recebidos
- Analise padrões de erro para identificar problemas recorrentes
- Use o
traceIdpara correlacionar erros com logs internos
-
Feedback ao Usuário
- Traduza os erros técnicos em mensagens amigáveis para o usuário final
- Forneça orientações claras sobre como corrigir os problemas
- Implemente um sistema de notificação para erros críticos
-
Monitoramento de Erros
- Configure dashboards específicos para monitorar taxas de erro
- Estabeleça alertas para picos de erros ou falhas recorrentes
- Revise periodicamente os erros mais comuns para melhorar a integração