Saltar al contenido principal

Webhooks

Los webhooks te permiten recibir notificaciones automaticas cada vez que cambia el estado de una orden. En lugar de consultar la API repetidamente (polling), Fletea envia un POST a tu URL cuando ocurre un evento.

Como funcionan

1

El proveedor notifica a Fletea

El proveedor logistico envia un webhook a Fletea cuando hay un cambio de estado en el envio.

2

Fletea actualiza la orden

Fletea actualiza la orden en su base de datos con el nuevo estado.

3

Fletea te notifica

Fletea envia un POST a cada webhook activo configurado en tu organizacion.

4

Tu servidor confirma

Tu servidor responde con 200 OK para confirmar recepcion.

Configurar webhooks

Desde el Dashboard

1

Abre Integraciones

Ve a Dashboard > Integraciones > Webhooks.

2

Crea el webhook

Haz clic en "Crear Webhook" e ingresa la URL de tu servidor.

3

Selecciona eventos

Elige que eventos deseas recibir.

4

Guarda el secret

Copia el secret generado. Lo necesitaras para verificar firmas.

Via API

POST /api/v1/webhooks

Scope requerido: webhooks:manage

curl -X POST https://app.fletea.mx/api/v1/webhooks \
-H "Authorization: Bearer flt_tu_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Mi servidor de produccion",
"url": "https://mi-servidor.com/webhooks/fletea",
"events": ["order.status_changed", "order.delivered", "order.failed"]
}'

Eventos disponibles

EventoDescripcion
order.createdSe creo una nueva orden
order.status_changedCualquier cambio de estado
order.picked_upPaquete recolectado
order.in_transitPaquete en transito
order.out_for_deliveryPaquete en reparto
order.deliveredPaquete entregado exitosamente
order.failedEntrega fallida
order.cancelledOrden cancelada
🚀
Un evento para todo

Si seleccionas order.status_changed, recibiras notificaciones de todos los cambios de estado. Es la opcion mas completa si quieres un solo webhook para todo.

Formato del payload

Cada webhook envia un payload JSON con esta estructura:

{
"id": "evt_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"event": "order.delivered",
"createdAt": "2026-03-03T14:30:00.000Z",
"data": {
"orderId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"internalReference": "PEDIDO-001",
"status": "delivered",
"providerData": {
"value": "HEX-123456789",
"location": "Monterrey",
"latitud": "25.6866",
"longitud": "-100.3161",
"observations": "Entregado en recepcion",
"dateTimeISO": "2026-03-03T14:30:00Z",
"StatusObj": {
"code": "DLV",
"description": "Entregado"
}
}
}
}

Headers del webhook

HeaderDescripcion
Content-Typeapplication/json
X-Fletea-EventNombre del evento (ej: order.delivered)
X-Fletea-SignatureFirma HMAC-SHA256 del payload

Verificacion de firma (HMAC-SHA256)

Cada webhook incluye una firma HMAC-SHA256 en el header X-Fletea-Signature. Verifica esta firma para asegurarte de que el webhook proviene de Fletea y no fue alterado.

La firma se calcula como: HMAC-SHA256(webhook_secret, request_body)

Node.js

const crypto = require('crypto');

function verifyFleteaWebhook(body, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');

return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}

// En tu servidor Express:
app.post('/webhooks/fletea', (req, res) => {
const signature = req.headers['x-fletea-signature'];
const rawBody = JSON.stringify(req.body);

if (!verifyFleteaWebhook(rawBody, signature, process.env.FLETEA_WEBHOOK_SECRET)) {
return res.status(401).json({ error: 'Firma invalida' });
}

const { event, data } = req.body;
console.log(`Evento: ${event}, Orden: ${data.orderId}, Estado: ${data.status}`);

// Procesar el evento...
res.status(200).json({ received: true });
});

Python

import hmac
import hashlib

def verify_fletea_webhook(body: str, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
body.encode(),
hashlib.sha256
).hexdigest()

return hmac.compare_digest(signature, expected)

# En tu servidor Flask:
@app.route('/webhooks/fletea', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-Fletea-Signature', '')
raw_body = request.get_data(as_text=True)

if not verify_fletea_webhook(raw_body, signature, WEBHOOK_SECRET):
return jsonify({'error': 'Firma invalida'}), 401

payload = request.get_json()
event = payload['event']
data = payload['data']

print(f"Evento: {event}, Orden: {data['orderId']}, Estado: {data['status']}")

return jsonify({'received': True}), 200

PHP

function verifyFleteaWebhook(string $body, string $signature, string $secret): bool {
$expected = hash_hmac('sha256', $body, $secret);
return hash_equals($expected, $signature);
}

// En tu controlador:
$body = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_FLETEA_SIGNATURE'] ?? '';

if (!verifyFleteaWebhook($body, $signature, $webhookSecret)) {
http_response_code(401);
echo json_encode(['error' => 'Firma invalida']);
exit;
}

$payload = json_decode($body, true);
$event = $payload['event'];
$data = $payload['data'];

// Procesar el evento...
http_response_code(200);
echo json_encode(['received' => true]);
⚠️
Siempre verifica la firma

Verifica la firma antes de procesar el webhook. Esto previene que un tercero envie payloads falsos a tu endpoint.

Reintentos

Si tu servidor no responde con un codigo 2xx, Fletea reintentara el webhook automaticamente:

IntentoEspera antes del reintento
1Inmediato
2~1.5 segundos
3~3 segundos

Cada intento tiene un timeout de 10 segundos.

Politica de reintentos:

  • Codigo 2xx: Exito, no se reintenta
  • Codigo 4xx: Error del cliente, no se reintenta (problema de configuracion de tu lado)
  • Codigo 5xx: Error del servidor, se reintenta
  • Timeout/error de red: Se reintenta
⚠️
Errores 4xx

Si tu servidor devuelve 4xx consistentemente, revisa la configuracion de tu webhook. Los errores 4xx no se reintentan porque generalmente indican un problema de configuracion.

Logs de entrega

Puedes consultar el historial de entregas de cada webhook desde Dashboard > Integraciones > Webhooks. Los logs muestran:

  • Fecha y hora de cada intento
  • Codigo de respuesta HTTP
  • Tiempo de respuesta
  • Payload enviado

Esto es util para depurar problemas de integracion.

Buenas practicas

  1. Responde rapido. Tu endpoint debe responder en menos de 10 segundos. Procesa la logica pesada de forma asincrona.
  2. Usa idempotencia. Tu servidor puede recibir el mismo evento mas de una vez. Usa el campo id del payload para deduplicar.
  3. Verifica la firma. Siempre valida X-Fletea-Signature antes de procesar.
  4. Usa HTTPS. Solo se admiten URLs con HTTPS en produccion.
  5. Maneja todos los eventos. Ignora gracefully los eventos que no reconoces. Fletea puede agregar nuevos en el futuro.