Saltar al contenido principal

Webhooks Personalizados

Conecta Fletea con cualquier sistema que puedas imaginar: tu ERP, CRM, plataforma de e-commerce propia, o cualquier servicio que pueda recibir peticiones HTTP.

Cada vez que cambia el estado de un envio, Fletea envia un POST a tu URL con los datos del evento.

app.fletea.mx
Configuracion de webhooks
Crea y gestiona tus webhooks desde la seccion de Integraciones

Crear un webhook

Desde el Dashboard

1

Abre la seccion de webhooks

Ve a Dashboard > Integraciones > Webhooks y haz clic en "Crear Webhook".

2

Configura los datos

Ingresa un nombre descriptivo (ej: "Mi ERP - Produccion"), la URL HTTPS de tu endpoint y selecciona los eventos que quieres recibir.

3

Guarda el secret

Al crear el webhook se genera un secret unico. Copialo inmediatamente, lo necesitaras para verificar la autenticidad de los webhooks.

⚠️
El secret solo se muestra una vez

Guardalo en un lugar seguro. Lo necesitaras para verificar la autenticidad de los webhooks que recibas.

Via API

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 ERP - Produccion",
"url": "https://mi-servidor.com/webhooks/fletea",
"events": [
"order.status_changed",
"order.delivered",
"order.failed"
]
}'

Eventos disponibles

EventoDescripcionCuando se dispara
order.createdOrden creadaAl crear una nueva orden
order.status_changedCambio de estadoCualquier transicion de estado
order.picked_upRecolectadoPaquete recogido por mensajero
order.in_transitEn transitoPaquete en camino
order.out_for_deliveryEn repartoPaquete salio a entrega
order.deliveredEntregadoEntrega exitosa confirmada
order.failedFallidoIntento de entrega fallido
order.cancelledCanceladoOrden cancelada
🚀
Un solo evento para todo

Suscribirte a order.status_changed cubre todos los cambios. Si solo necesitas saber cuando se entrega o falla, usa order.delivered y order.failed.

Esquema del payload

Todos los eventos comparten la misma 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, NL",
"latitud": "25.6866",
"longitud": "-100.3161",
"observations": "Entregado en recepcion",
"dateTimeISO": "2026-03-03T14:30:00Z",
"StatusObj": {
"code": "DLV",
"description": "Entregado"
}
}
}
}

Campos del payload

CampoTipoDescripcion
idstringID unico del evento (UUID v4)
eventstringTipo de evento (ej: order.delivered)
createdAtstringFecha ISO 8601 del evento
data.orderIdstringUUID de la orden en Fletea
data.internalReferencestringTu referencia interna
data.statusstringNuevo estado de la orden
data.providerDataobjectDatos crudos del proveedor logistico

Datos del proveedor (providerData)

CampoDescripcion
valueNumero de guia
locationUbicacion del evento
latitud / longitudCoordenadas GPS (cuando disponibles)
observationsNotas del proveedor
dateTimeISOFecha del evento del proveedor
StatusObj.codeCodigo original del proveedor
StatusObj.descriptionDescripcion del proveedor

Verificacion de firma

Cada webhook incluye el header X-Fletea-Signature con una firma HMAC-SHA256. Siempre verifica esta firma antes de procesar.

Node.js

const crypto = require('crypto');
const express = require('express');
const app = express();

app.use(express.json());

const WEBHOOK_SECRET = process.env.FLETEA_WEBHOOK_SECRET;

app.post('/webhooks/fletea', (req, res) => {
// 1. Obtener firma del header
const signature = req.headers['x-fletea-signature'];
if (!signature) {
return res.status(401).json({ error: 'Firma faltante' });
}

// 2. Calcular firma esperada
const body = JSON.stringify(req.body);
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(body)
.digest('hex');

// 3. Comparar de forma segura (timing-safe)
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).json({ error: 'Firma invalida' });
}

// 4. Procesar el evento
const { event, data } = req.body;

switch (event) {
case 'order.delivered':
console.log(`Orden ${data.internalReference} entregada`);
// Actualizar tu sistema...
break;
case 'order.failed':
console.log(`Orden ${data.internalReference} fallida`);
// Notificar a tu equipo...
break;
default:
console.log(`Evento no manejado: ${event}`);
}

res.status(200).json({ received: true });
});

app.listen(3000);

Python (Flask)

import hmac
import hashlib
import json
import os
from flask import Flask, request, jsonify

app = Flask(__name__)
WEBHOOK_SECRET = os.environ['FLETEA_WEBHOOK_SECRET']

@app.route('/webhooks/fletea', methods=['POST'])
def handle_webhook():
# 1. Obtener firma del header
signature = request.headers.get('X-Fletea-Signature', '')
if not signature:
return jsonify({'error': 'Firma faltante'}), 401

# 2. Calcular firma esperada
body = request.get_data(as_text=True)
expected = hmac.new(
WEBHOOK_SECRET.encode(),
body.encode(),
hashlib.sha256
).hexdigest()

# 3. Comparar de forma segura
if not hmac.compare_digest(signature, expected):
return jsonify({'error': 'Firma invalida'}), 401

# 4. Procesar el evento
payload = request.get_json()
event = payload['event']
data = payload['data']

if event == 'order.delivered':
print(f"Orden {data['internalReference']} entregada")
# Actualizar tu sistema...
elif event == 'order.failed':
print(f"Orden {data['internalReference']} fallida")
# Notificar a tu equipo...

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

PHP

<?php

$webhookSecret = $_ENV['FLETEA_WEBHOOK_SECRET'];
$body = file_get_contents('php://input');

// 1. Obtener firma del header
$signature = $_SERVER['HTTP_X_FLETEA_SIGNATURE'] ?? '';
if (empty($signature)) {
http_response_code(401);
echo json_encode(['error' => 'Firma faltante']);
exit;
}

// 2. Calcular firma esperada
$expected = hash_hmac('sha256', $body, $webhookSecret);

// 3. Comparar de forma segura
if (!hash_equals($expected, $signature)) {
http_response_code(401);
echo json_encode(['error' => 'Firma invalida']);
exit;
}

// 4. Procesar el evento
$payload = json_decode($body, true);
$event = $payload['event'];
$data = $payload['data'];

switch ($event) {
case 'order.delivered':
error_log("Orden {$data['internalReference']} entregada");
// Actualizar tu sistema...
break;
case 'order.failed':
error_log("Orden {$data['internalReference']} fallida");
// Notificar a tu equipo...
break;
}

http_response_code(200);
echo json_encode(['received' => true]);

Pruebas de webhooks

Con ngrok (desarrollo local)

1

Instala ngrok

Descarga desde ngrok.com e instalalo.

2

Inicia tu servidor

Ejecuta tu servidor local en el puerto 3000 (o el que uses).

3

Crea un tunel

Ejecuta ngrok http 3000 y usa la URL generada (ej: https://abc123.ngrok-free.app/webhooks/fletea) al crear tu webhook en Fletea.

Con webhook.site

Para verificar rapidamente que los webhooks llegan:

  1. Ve a webhook.site y copia tu URL unica
  2. Usala como URL del webhook en Fletea
  3. Crea o actualiza una orden para disparar un evento
  4. Verifica el payload en webhook.site

Logs de entrega

Puedes consultar el historial completo de cada webhook desde Dashboard > Integraciones > Webhooks:

CampoDescripcion
FechaCuando se envio el webhook
EventoTipo de evento disparado
Codigo HTTPRespuesta de tu servidor
TiempoDuracion de la peticion
ReintentosNumero de intentos realizados

Politica de reintentos

IntentoEsperaTimeout
1Inmediato10 segundos
2~1.5 segundos10 segundos
3~3 segundos10 segundos
  • Los errores 4xx no se reintentan (indican error de configuracion)
  • Los errores 5xx y timeouts se reintentan hasta 3 veces
  • Despues de 3 intentos fallidos, el evento se registra como fallido en los logs

Buenas practicas

  1. Responde en menos de 10 segundos. Si necesitas procesamiento pesado, guarda el evento en una cola y procesalo despues.

  2. Usa idempotencia. El campo id del payload es unico. Guardalo para evitar procesar el mismo evento dos veces.

  3. Verifica siempre la firma. Es tu unica garantia de que el webhook viene de Fletea.

  4. Solo HTTPS. No se admiten URLs sin SSL en produccion.

  5. Maneja eventos desconocidos. Ignora los eventos que no reconoces con un 200 OK. Fletea puede agregar nuevos tipos de eventos en el futuro.

💡
Desactivacion automatica

Si tu webhook falla consistentemente, Fletea puede desactivarlo automaticamente para no saturar tu servidor. Revisa los logs regularmente.