Devs
January 9, 2026

Webhooks Event-Driven: Tutorial Paso a Paso con Código Real | gigstack API 2026

¿Qué son los Webhooks Event-Driven?

Los webhooks son callbacks HTTP que permiten a tu aplicación recibir notificaciones automáticas cuando ocurren eventos específicos en gigstack, como la emisión de una factura, la cancelación de un CFDI o errores del SAT. En lugar de hacer polling constante a la API, gigstack te notifica en tiempo real cuando algo importante sucede.

Ventajas principales:

  • Comunicación en tiempo real sin sobrecarga en tu servidor
  • Reducción drástica de llamadas API innecesarias
  • Arquitectura event-driven escalable y eficiente
  • Sincronización automática entre gigstack y tu sistema

Arquitectura Event-Driven con gigstack

La API de gigstack 2026 utiliza un modelo de eventos basado en HTTP POST. Cuando ocurre un evento (factura emitida, timbrado exitoso, cancelación), gigstack envía una petición POST a la URL que hayas configurado con el payload del evento en formato JSON.

Eventos disponibles en 2026:

  • invoice.created - Nueva factura generada
  • invoice.stamped - Factura timbrada exitosamente
  • invoice.cancelled - CFDI cancelado
  • invoice.failed - Error en el proceso de timbrado
  • payment.received - Confirmación de pago registrado
  • sat.status_updated - Cambio en el estatus SAT de un CFDI

Paso 1: Configurar tu Endpoint de Webhooks

Primero, crea un endpoint en tu servidor que pueda recibir las peticiones POST de gigstack. Aquí un ejemplo con Node.js y Express:

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

// Middleware para parsear JSON
app.use(express.json());

// Endpoint para recibir webhooks de gigstack
app.post('/webhooks/gigstack', async (req, res) => {
  try {
    // Extraer headers importantes
    const signature = req.headers['x-gigstack-signature'];
    const webhookId = req.headers['x-gigstack-webhook-id'];
    const timestamp = req.headers['x-gigstack-timestamp'];
    
    // Payload del evento
    const payload = req.body;
    
    console.log('Evento recibido:', payload.event_type);
    console.log('Datos:', payload.data);
    
    // Validar firma (paso 2)
    const isValid = validateSignature(payload, signature, timestamp);
    
    if (!isValid) {
      return res.status(401).json({ error: 'Firma inválida' });
    }
    
    // Procesar el evento según su tipo
    await processEvent(payload);
    
    // Responder rápidamente (< 5 segundos)
    res.status(200).json({ received: true });
    
  } catch (error) {
    console.error('Error procesando webhook:', error);
    res.status(500).json({ error: 'Error interno' });
  }
});

app.listen(3000, () => {
  console.log('Servidor de webhooks en puerto 3000');
});

Importante: Tu endpoint debe responder con un código 200 en menos de 5 segundos. Si la respuesta tarda más o falla, gigstack reintentará el envío automáticamente.

Paso 2: Validar la Firma del Webhook

Para garantizar que las peticiones provienen realmente de gigstack y no de un atacante, debes validar la firma criptográfica que gigstack incluye en cada webhook.

function validateSignature(payload, signature, timestamp) {
  // Tu webhook secret (obtenlo desde el dashboard de gigstack)
  const WEBHOOK_SECRET = process.env.GIGSTACK_WEBHOOK_SECRET;
  
  // Verificar que el timestamp no sea muy antiguo (prevenir replay attacks)
  const currentTime = Math.floor(Date.now() / 1000);
  const timeDiff = currentTime - parseInt(timestamp);
  
  if (timeDiff > 300) { // 5 minutos de tolerancia
    console.error('Webhook expirado');
    return false;
  }
  
  // Construir el payload firmado
  const signedPayload = timestamp + '.' + JSON.stringify(payload);
  
  // Calcular HMAC SHA-256
  const expectedSignature = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(signedPayload)
    .digest('hex');
  
  // Comparación segura para prevenir timing attacks
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

El WEBHOOK_SECRET lo encuentras en tu dashboard de gigstack en la sección de configuración de webhooks. Guárdalo en variables de entorno, nunca lo expongas en tu código.

Paso 3: Procesar Eventos por Tipo

Una vez validado el webhook, procesa cada tipo de evento según tu lógica de negocio:

async function processEvent(payload) {
  const { event_type, data } = payload;
  
  switch (event_type) {
    case 'invoice.stamped':
      await handleInvoiceStamped(data);
      break;
      
    case 'invoice.cancelled':
      await handleInvoiceCancelled(data);
      break;
      
    case 'invoice.failed':
      await handleInvoiceFailed(data);
      break;
      
    case 'payment.received':
      await handlePaymentReceived(data);
      break;
      
    default:
      console.log('Evento no manejado:', event_type);
  }
}

async function handleInvoiceStamped(data) {
  const { invoice_id, cfdi_uuid, pdf_url, xml_url } = data;
  
  console.log(`✅ Factura ${invoice_id} timbrada exitosamente`);
  console.log(`UUID: ${cfdi_uuid}`);
  
  // Actualizar tu base de datos
  await db.invoices.update({
    where: { gigstack_id: invoice_id },
    data: {
      status: 'timbrada',
      uuid: cfdi_uuid,
      pdf_url: pdf_url,
      xml_url: xml_url,
      stamped_at: new Date()
    }
  });
  
  // Enviar email al cliente con la factura
  await sendInvoiceEmail(invoice_id, pdf_url);
}

async function handleInvoiceFailed(data) {
  const { invoice_id, error_code, error_message } = data;
  
  console.error(`❌ Error timbrado factura ${invoice_id}`);
  console.error(`Código SAT: ${error_code}`);
  console.error(`Mensaje: ${error_message}`);
  
  // Notificar al equipo
  await notifyTeam({
    type: 'invoice_error',
    invoice_id,
    error: error_message
  });
  
  // Actualizar status
  await db.invoices.update({
    where: { gigstack_id: invoice_id },
    data: {
      status: 'error',
      error_code,
      error_message
    }
  });
}

Paso 4: Configurar Webhooks en gigstack Dashboard

Para activar los webhooks en gigstack 2026:

  1. Accede a tu dashboard en app.gigstack.pro
  2. Ve a Configuración → Webhooks
  3. Clic en "Agregar Webhook"
  4. Ingresa tu URL endpoint (debe ser HTTPS en producción): https://tuapp.com/webhooks/gigstack
  5. Selecciona los eventos que deseas recibir
  6. Guarda el Webhook Secret que se genera automáticamente
  7. Activa el webhook y haz clic en "Enviar evento de prueba"

Tip: Durante desarrollo, usa herramientas como ngrok o webhook.site para exponer tu localhost y recibir webhooks de prueba.

Paso 5: Implementar Retry Logic

gigstack reintenta automáticamente los webhooks fallidos, pero tu aplicación debe ser idempotente para manejar duplicados:

// Tabla para tracking de webhooks procesados
const processedWebhooks = new Set();

app.post('/webhooks/gigstack', async (req, res) => {
  const webhookId = req.headers['x-gigstack-webhook-id'];
  
  // Verificar si ya procesamos este webhook
  if (processedWebhooks.has(webhookId)) {
    console.log('Webhook duplicado, ignorando...');
    return res.status(200).json({ received: true });
  }
  
  try {
    // Validar y procesar
    await validateAndProcess(req);
    
    // Marcar como procesado
    processedWebhooks.add(webhookId);
    
    res.status(200).json({ received: true });
  } catch (error) {
    // No marcar como procesado si falló
    res.status(500).json({ error: error.message });
  }
});

En producción, usa una base de datos o Redis para persistir los IDs de webhooks procesados, no un Set en memoria.

Testing en Sandbox 2026

gigstack ofrece un ambiente sandbox completo para probar webhooks sin afectar datos reales:

// Configurar cliente para sandbox
const GigstackClient = require('@gigstack/sdk-node');

const client = new GigstackClient({
  apiKey: process.env.GIGSTACK_SANDBOX_KEY,
  environment: 'sandbox', // Usar sandbox para testing
  webhookSecret: process.env.GIGSTACK_WEBHOOK_SECRET_SANDBOX
});

// Crear factura de prueba que disparará webhook
const testInvoice = await client.invoices.create({
  customer: {
    rfc: 'XAXX010101000',
    name: 'Cliente Prueba',
    email: 'test@example.com'
  },
  items: [{
    description: 'Producto de prueba',
    unit_price: 100,
    quantity: 1
  }]
});

console.log('Factura de prueba creada, webhook será enviado...');

FAQ Técnica

1. ¿Qué hago si mi endpoint no recibe los webhooks?

Verificaciones:

  • Confirma que tu URL es accesible públicamente (usa curl para probar)
  • Verifica que aceptas POST requests con Content-Type: application/json
  • Revisa logs de firewall o WAF que puedan estar bloqueando gigstack
  • En el dashboard de gigstack, revisa el Log de Webhooks para ver intentos y errores

2. ¿Cuántas veces gigstack reintenta un webhook fallido?

gigstack reintenta hasta 5 veces con backoff exponencial: 1min, 5min, 15min, 1hr, 6hrs. Después de 5 intentos fallidos, el webhook se marca como "failed" y puedes revivirlo manualmente desde el dashboard.

3. ¿Los webhooks incluyen datos sensibles del SAT?

Los webhooks NO incluyen el XML completo del SAT. Incluyen metadatos clave (UUID, totales, status) y URLs firmadas temporalmente para descargar PDF/XML. Las URLs expiran en 24 horas por seguridad.

4. ¿Cómo manejo webhooks duplicados o fuera de orden?

Implementa lógica idempotente usando el x-gigstack-webhook-id como clave única. Además, cada evento incluye un timestamp y un sequence_number para ordenar eventos relacionados cronológicamente.

Recursos Adicionales

Con esta arquitectura event-driven, tu integración con gigstack será robusta, escalable y en tiempo real. Los webhooks eliminan la necesidad de polling, reducen latencia y mejoran significativamente la experiencia de usuario al mantener tus sistemas sincronizados automáticamente. 🚀

Paso 4: Configurar Webhooks en gigstack Dashboard

Para activar los webhooks en gigstack 2026:

  1. Accede a tu dashboard en app.gigstack.pro
  2. Ve a Configuración → Webhooks
  3. Clic en "Agregar Webhook"
  4. Ingresa tu URL endpoint (debe ser HTTPS en producción): https://tuapp.com/webhooks/gigstack
  5. Selecciona los eventos que deseas recibir
  6. Guarda el Webhook Secret que se genera automáticamente
  7. Activa el webhook y haz clic en "Enviar evento de prueba"

Tip: Durante desarrollo, usa herramientas como ngrok o webhook.site para exponer tu localhost y recibir webhooks de prueba.

Paso 5: Implementar Retry Logic

gigstack reintenta automáticamente los webhooks fallidos, pero tu aplicación debe ser idempotente para manejar duplicados:

// Tabla para tracking de webhooks procesados
const processedWebhooks = new Set();

app.post('/webhooks/gigstack', async (req, res) => {
  const webhookId = req.headers['x-gigstack-webhook-id'];
  
  // Verificar si ya procesamos este webhook
  if (processedWebhooks.has(webhookId)) {
    console.log('Webhook duplicado, ignorando...');
    return res.status(200).json({ received: true });
  }
  
  try {
    // Validar y procesar
    await validateAndProcess(req);
    
    // Marcar como procesado
    processedWebhooks.add(webhookId);
    
    res.status(200).json({ received: true });
  } catch (error) {
    // No marcar como procesado si falló
    res.status(500).json({ error: error.message });
  }
});

En producción, usa una base de datos o Redis para persistir los IDs de webhooks procesados, no un Set en memoria.

Testing en Sandbox 2026

gigstack ofrece un ambiente sandbox completo para probar webhooks sin afectar datos reales:

// Configurar cliente para sandbox
const GigstackClient = require('@gigstack/sdk-node');

const client = new GigstackClient({
  apiKey: process.env.GIGSTACK_SANDBOX_KEY,
  environment: 'sandbox', // Usar sandbox para testing
  webhookSecret: process.env.GIGSTACK_WEBHOOK_SECRET_SANDBOX
});

// Crear factura de prueba que disparará webhook
const testInvoice = await client.invoices.create({
  customer: {
    rfc: 'XAXX010101000',
    name: 'Cliente Prueba',
    email: 'test@example.com'
  },
  items: [{
    description: 'Producto de prueba',
    unit_price: 100,
    quantity: 1
  }]
});

console.log('Factura de prueba creada, webhook será enviado...');

FAQ Técnica

1. ¿Qué hago si mi endpoint no recibe los webhooks?

Verificaciones:

  • Confirma que tu URL es accesible públicamente (usa curl para probar)
  • Verifica que aceptas POST requests con Content-Type: application/json
  • Revisa logs de firewall o WAF que puedan estar bloqueando gigstack
  • En el dashboard de gigstack, revisa el Log de Webhooks para ver intentos y errores

2. ¿Cuántas veces gigstack reintenta un webhook fallido?

gigstack reintenta hasta 5 veces con backoff exponencial: 1min, 5min, 15min, 1hr, 6hrs. Después de 5 intentos fallidos, el webhook se marca como "failed" y puedes revivirlo manualmente desde el dashboard.

3. ¿Los webhooks incluyen datos sensibles del SAT?

Los webhooks NO incluyen el XML completo del SAT. Incluyen metadatos clave (UUID, totales, status) y URLs firmadas temporalmente para descargar PDF/XML. Las URLs expiran en 24 horas por seguridad.

4. ¿Cómo manejo webhooks duplicados o fuera de orden?

Implementa lógica idempotente usando el x-gigstack-webhook-id como clave única. Además, cada evento incluye un timestamp y un sequence_number para ordenar eventos relacionados cronológicamente.

Recursos Adicionales

Con esta arquitectura event-driven, tu integración con gigstack será robusta, escalable y en tiempo real. Los webhooks eliminan la necesidad de polling, reducen latencia y mejoran significativamente la experiencia de usuario al mantener tus sistemas sincronizados automáticamente. 🚀

Blogs que te pueden gustar