Notificacao via Callback
Muitas operacoes nas APIs da I-Systems sao assincronas. Quando voce cria um pedido (Serviceordering), agendamento (appointment) e Reparo (Troubleticket), o processamento pode levar alguns minutos. Para manter voce informado sobre mudancas de estado, enviamos notificacoes via webhook para um endpoint que voce configurar.
Importante: Liberação de Firewall
Antes de utilizar as notificações via callback, você deve informar o endpoint (URL) do seu servidor para nossa equipe realizar a liberação no firewall. Sem essa liberação, nossos servidores não conseguirão enviar as notificações para o seu endpoint.
Como Funciona
Voce faz uma requisicao
Cria um Service Order, Appointment, etc.
API retorna resposta inicial
Voce recebe o recurso criado com estado inicial (ex: "acknowledged")
Processamento assincrono
Nossa plataforma processa a solicitacao em background
Notificacao via callback
Enviamos POST para seu endpoint com atualizacoes de estado
Configurando seu Endpoint de Callback
Requisitos do Endpoint
URL Publica e Acessivel
Seu endpoint deve estar acessivel pela internet via HTTPS
Suporte a HTTPS
Por seguranca, apenas endpoints HTTPS sao aceitos
Resposta Rapida
Retorne status 200-299 em ate 5 segundos
Idempotencia
Prepare-se para receber a mesma notificacao mais de uma vez
Como Configurar
O endpoint de callback e configurado por requisicao, no momento da criacao do recurso. Cada API que suporta callbacks tem um atributo especifico:
- Service Order:
callbackno corpo da requisicao - Appointment:
callbackno corpo da requisicao - Trouble Ticket:
callbackno corpo da requisicao
Exemplos de Configuracao
Criando Service Order com Callback
Request
curl --location 'https://apim-isystems-uat-brzsth-001.ihstowers.com/serviceOrderingManagement/serviceOrder' \
--header 'x-service-provider: {{x-service-provider}}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng...' \
--data '{
"externalId": "Integracao-Int24",
"category": "SERVICE.ORDER",
"serviceOrderItem": [
{
"id": "sfttp-1",
"action": "create",
"service": {
"id": "1111111110",
"serviceSpecification": {
"id": "CFS.FTTP.BASICO"
},
"serviceCharacteristic": [
{
"name": "serviceProfile",
"value": "ISYS_FTTP_400M"
},
{
"name": "addressId",
"value": "0001231512"
}
]
}
}
],
"relatedParty": {
"correlationId": "Integracao-Int24"
}
}'Response
{
"id": "a96e34d7-fe6f-4306-b3bd-9616edb6314b9",
"orderDate": "2025-10-23T17:16:43",
"state": "Acknowledged"
}externalId: Identificador unico da sua aplicacao para rastrear o pedidocategory: Categoria do pedido (SERVICE.ORDER)action: Acao a ser executada (create, modify, delete)serviceSpecification.id: ID da especificacao do servico (ex: CFS.FTTP.BASICO)serviceProfile: Perfil de velocidade (ex: ISYS_FTTP_400M)addressId: ID do endereco previamente qualificadocorrelationId: ID de correlacao para rastreamento
Formato das Notificacoes
Estrutura da Notificacao
As notificacoes sao enviadas via HTTP POST para o endpoint configurado. O corpo da requisicao contem o recurso completo atualizado com seu novo estado.
Service Order State Change Notification
POST https://seu-sistema.com.br/api/webhooks/service-orders
Content-Type: application/json
{
"id": "a96e34d7-fe6f-4306-b3bd-9616edb6314b9",
"state": "Completed",
"orderDate": "2025-10-23T17:26:50.4410000Z",
"externalId": "Integracao-Int24",
"details": [],
"serviceOrderItem": [
{
"id": "sfttp-1",
"action": "create",
"service": {
"id": "1111111110",
"category": "CFS",
"serviceSpecification": {
"id": "CFS.FTTP.BASICO"
},
"serviceCharacteristic": [
{
"name": "serviceProfile",
"value": "ISYS_FTTP_400M"
},
{
"name": "addressId",
"value": "0001231512"
}
]
}
}
],
"relatedParty": {}
}Acknowledged: Pedido recebido e em fila para processamentoInProgress: Pedido em processamentoCompleted: Pedido concluido com sucessoFailed: Pedido falhou durante o processamentoCancelled: Pedido cancelado
Appointment State Change Notification
POST https://seu-sistema.com.br/api/webhooks/appointments
Content-Type: application/json
{
"id": "006",
"name": "ACTIVITY_CREATED",
"timeOcurred": "2023-01-23T06:58:10Z",
"event": {
"appointment": {
"serviceAppointmentId": "SA-562403",
"workOrderId": "00001192",
"status": "Atribuído",
"category": "Instalacao BL",
"serviceType": "FTTH",
"relatedParty": [
{
"id": "roberto.silva@email.com",
"name": "Roberto da Silva",
"role": "technician"
},
{
"id": "6deea995-05bc-49d7-b990-4bdf443fb80e4098",
"role": "orderId"
}
],
"customer": {
"name": "Eduardo Franco",
"serviceId": "TEN|353573730",
"contactMedium": [
{
"characteristic": {
"phoneNumber": "21965874562"
}
}
]
},
"validFor": {
"startDateTime": "2023-01-23T06:58:10Z",
"endDateTime": "2023-01-23T06:58:10Z"
}
}
}
}name: Tipo do evento (ACTIVITY_CREATED, ACTIVITY_UPDATED, etc.)serviceAppointmentId: ID do agendamentoworkOrderId: ID da ordem de servico associadastatus: Estado atual (Atribuído, Em Andamento, Concluído, etc.)category: Categoria da atividade (Instalacao BL, Reparo, etc.)serviceType: Tipo de servico (FTTH, FTTP, FTTO)relatedParty: Tecnico e ID do pedido relacionadocustomer: Informacoes do cliente finalvalidFor: Janela de agendamento
Trouble Ticket State Change Notification
POST https://seu-sistema.com.br/api/webhooks/tickets
Content-Type: application/json
{
"id": "TT_00000183-2022",
"creationDate": "2022-12-29T10:00:27Z",
"description": "Correcao.",
"category": "Corrective",
"expectedResolutionDate": "2022-12-29T10:00:27Z",
"resolutionDate": "2022-12-29T10:00:27Z",
"status": "Resolved",
"correctAddress": "Endereço novo",
"relatedParty": [
{
"role": "Corrective",
"lastComment": "Ultimo Comentario"
}
],
"propertiesForm": [
{
"name": "Motivo nao validacao",
"value": "Velocidade não atingida"
},
{
"name": "Responsavel certificacao",
"value": "COP"
},
{
"name": "Status validacao cert",
"value": "Ok"
}
]
}id: ID unico do ticket (ex: TT_00000183-2022)status: Estado atual (Resolved, InProgress, Pending, etc.)category: Categoria do ticket (Corrective, Preventive, etc.)description: Descricao do problemacreationDate: Data de criacao do ticketexpectedResolutionDate: Data esperada de resolucaoresolutionDate: Data efetiva da resolucaocorrectAddress: Endereco corrigido (se aplicavel)relatedParty: Informacoes sobre responsaveis e comentariospropertiesForm: Campos customizados com informacoes adicionais
Implementando o Endpoint de Callback
Exemplo de Implementacao
Node.js (Express)
const express = require('express');
const app = express();
app.use(express.json());
// Endpoint para receber notificacoes de Service Orders
app.post('/api/webhooks/service-orders', async (req, res) => {
try {
const serviceOrder = req.body;
// Log da notificacao recebida
console.log('Notificacao recebida:', {
id: serviceOrder.id,
externalId: serviceOrder.externalId,
state: serviceOrder.state,
orderDate: serviceOrder.orderDate
});
// Processar a notificacao de forma assincrona
processServiceOrderNotification(serviceOrder)
.catch(err => console.error('Erro ao processar notificacao:', err));
// Retornar resposta rapida (nao esperar processamento)
res.status(200).json({ received: true });
} catch (error) {
console.error('Erro ao receber notificacao:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
async function processServiceOrderNotification(serviceOrder) {
// Verificar idempotencia (evitar processar duplicatas)
const alreadyProcessed = await checkIfEventProcessed(serviceOrder.id);
if (alreadyProcessed) {
console.log('Pedido ja processado:', serviceOrder.id);
return;
}
// Salvar que este pedido foi processado
await markEventAsProcessed(serviceOrder.id);
// Atualizar seu sistema baseado no novo estado
switch (serviceOrder.state) {
case 'Acknowledged':
await updateOrderStatus(serviceOrder.externalId, 'RECEBIDO');
await notifyCustomer(serviceOrder.externalId, 'Seu pedido foi recebido');
break;
case 'InProgress':
await updateOrderStatus(serviceOrder.externalId, 'EM_ANDAMENTO');
await notifyCustomer(serviceOrder.externalId, 'Seu pedido esta em andamento');
break;
case 'Completed':
await updateOrderStatus(serviceOrder.externalId, 'CONCLUIDO');
await notifyCustomer(serviceOrder.externalId, 'Seu pedido foi concluido');
break;
case 'Failed':
await updateOrderStatus(serviceOrder.externalId, 'FALHOU');
await notifyCustomer(serviceOrder.externalId, 'Houve um problema com seu pedido');
break;
case 'Cancelled':
await updateOrderStatus(serviceOrder.externalId, 'CANCELADO');
await notifyCustomer(serviceOrder.externalId, 'Seu pedido foi cancelado');
break;
default:
console.log('Estado desconhecido:', serviceOrder.state);
}
}
// Funcoes auxiliares (implementar conforme sua necessidade)
async function checkIfEventProcessed(orderId) {
// Verificar no banco de dados se este orderId ja foi processado
// Retorna true se ja foi processado, false caso contrario
}
async function markEventAsProcessed(orderId) {
// Salvar no banco de dados que este pedido foi processado
// Incluir timestamp para auditoria
}
async function updateOrderStatus(externalId, status) {
// Atualizar status do pedido no seu sistema
}
async function notifyCustomer(externalId, message) {
// Enviar notificacao para o cliente (email, SMS, push, etc)
}
app.listen(3000, () => {
console.log('Servidor rodando na porta 3000');
});Python (Flask)
from flask import Flask, request, jsonify
import logging
from datetime import datetime
app = Flask(__name__)
logging.basicConfig(level=logging.INFO)
@app.route('/api/webhooks/service-orders', methods=['POST'])
def service_order_webhook():
try:
service_order = request.get_json()
# Log da notificacao
logging.info(f"Notificacao recebida: {service_order.get('id')}")
# Processar de forma assincrona
process_service_order_notification(service_order)
# Retornar resposta rapida
return jsonify({"received": True}), 200
except Exception as e:
logging.error(f"Erro ao processar webhook: {str(e)}")
return jsonify({"error": "Internal server error"}), 500
def process_service_order_notification(service_order):
order_id = service_order.get('id')
external_id = service_order.get('externalId')
state = service_order.get('state')
# Verificar idempotencia
if check_if_event_processed(order_id):
logging.info(f"Pedido ja processado: {order_id}")
return
# Marcar como processado
mark_event_as_processed(order_id)
# Processar baseado no estado
if state == 'Acknowledged':
update_order_status(external_id, 'RECEBIDO')
notify_customer(external_id, 'Seu pedido foi recebido')
elif state == 'InProgress':
update_order_status(external_id, 'EM_ANDAMENTO')
notify_customer(external_id, 'Seu pedido esta em andamento')
elif state == 'Completed':
update_order_status(external_id, 'CONCLUIDO')
notify_customer(external_id, 'Seu pedido foi concluido')
elif state == 'Failed':
update_order_status(external_id, 'FALHOU')
notify_customer(external_id, 'Houve um problema')
elif state == 'Cancelled':
update_order_status(external_id, 'CANCELADO')
notify_customer(external_id, 'Seu pedido foi cancelado')
def check_if_event_processed(order_id):
# Implementar verificacao no banco de dados
pass
def mark_event_as_processed(order_id):
# Implementar gravacao no banco de dados
pass
def update_order_status(external_id, status):
# Implementar atualizacao de status
pass
def notify_customer(external_id, message):
# Implementar notificacao ao cliente
pass
if __name__ == '__main__':
app.run(port=3000)Boas Praticas
Responda Rapidamente
Retorne HTTP 200-299 imediatamente. Processe a notificacao de forma assincrona apos retornar a resposta.
Implemente Idempotencia
Use o campo id do pedido para detectar e ignorar notificacoes duplicadas. Armazene IDs de pedidos ja processados com seus estados.
Valide a Origem
Considere implementar validacao de origem (IP whitelist, assinatura HMAC) para garantir que callbacks vem da I-Systems.
Trate Erros Graciosamente
Se seu endpoint falhar, iremos tentar reenviar a notificacao. Implemente logs detalhados para debugging.
Use Filas
Para alto volume, considere usar filas de mensagens (SQS, RabbitMQ) para processar callbacks de forma confiavel.
Monitore seu Endpoint
Configure alertas para monitorar disponibilidade e tempo de resposta do seu endpoint de callback.
Politica de Retry
Se seu endpoint falhar ao receber uma notificacao, tentaremos reenviar ate 3 vezes
Cenarios de Retry
- Falhas gerais: Ate 3 tentativas de notificacao
- Erros de autenticacao (401/403/440): Ate 6 tentativas (com renovacao de token)
- Erros 400/412: Sem retry (descartado imediatamente)
Importante: Apos esgotar as tentativas, a notificacao e descartada. Voce pode consultar o estado atual do recurso via API a qualquer momento.