Devs
January 16, 2026

Stripe + gigstack con Código Real: Tutorial Paso a Paso para Facturación Automática | gigstack API 2026

Si cobras pagos con Stripe en México, necesitas facturar cada transacción. Hacerlo manualmente es un desperdicio de tiempo. En este tutorial técnico, te muestro cómo conectar Stripe con gigstack usando código real en Node.js para automatizar completamente tu facturación.

¿Por qué Stripe + gigstack?

Stripe procesa tus pagos, gigstack se encarga del SAT. Cero intervención manual, cero errores de RFC, facturas entregadas automáticamente a tus clientes en segundos.

Casos de uso comunes:

  • SaaS con suscripciones recurrentes
  • Marketplaces que cobran comisiones
  • E-commerce con pagos únicos
  • Plataformas de servicios con pagos escalonados

Prerequisitos Técnicos

Antes de empezar, asegúrate de tener:

  • Cuenta activa en Stripe
  • Cuenta en gigstack con API keys
  • Node.js 18+ instalado
  • Conocimientos básicos de Express.js y webhooks

Paso 1: Instalación y Configuración Inicial

Primero, instala las dependencias necesarias:

npm install stripe express dotenv @gigstack/sdk-node

Crea tu archivo .env con tus credenciales:

STRIPE_SECRET_KEY=sk_test_tu_clave_stripe
STRIPE_WEBHOOK_SECRET=whsec_tu_webhook_secret
GIGSTACK_API_KEY=gsk_live_tu_clave_gigstack
GIGSTACK_ENDPOINT=https://api.gigstack.io/v1

Paso 2: Configurar el Webhook de Stripe

Crea un endpoint que escuche eventos de Stripe. Este código captura pagos exitosos y dispara la facturación:

const express = require('express');
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
const { GigstackClient } = require('@gigstack/sdk-node');

const app = express();
const gigstack = new GigstackClient({
  apiKey: process.env.GIGSTACK_API_KEY,
  endpoint: process.env.GIGSTACK_ENDPOINT
});

app.post('/webhooks/stripe', 
  express.raw({ type: 'application/json' }), 
  async (req, res) => {
    const sig = req.headers['stripe-signature'];
    let event;

    try {
      event = stripe.webhooks.constructEvent(
        req.body, 
        sig, 
        process.env.STRIPE_WEBHOOK_SECRET
      );
    } catch (err) {
      console.error('⚠️  Webhook signature verification failed:', err.message);
      return res.status(400).send(`Webhook Error: ${err.message}`);
    }

    // Manejar evento de pago exitoso
    if (event.type === 'payment_intent.succeeded') {
      const paymentIntent = event.data.object;
      await generarFactura(paymentIntent);
    }

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

Paso 3: Función para Generar Factura

Esta es la función crítica que conecta el pago de Stripe con gigstack:

async function generarFactura(paymentIntent) {
  try {
    // Extraer metadata del cliente (debe incluirse al crear PaymentIntent)
    const { rfc, email, razon_social, uso_cfdi, metodo_pago } = paymentIntent.metadata;
    
    // Validar RFC antes de facturar
    if (!rfc || rfc.length < 12) {
      throw new Error('RFC inválido en metadata');
    }

    // Preparar items de la factura
    const items = [{
      cantidad: 1,
      clave_producto_servicio: '81112100', // Consultoría en software
      clave_unidad: 'E48', // Unidad de servicio
      descripcion: paymentIntent.description || 'Servicio de suscripción',
      valor_unitario: paymentIntent.amount / 100, // Stripe usa centavos
      impuestos: [{
        tipo: 'IVA',
        tasa: 0.16,
        retencion: false
      }]
    }];

    // Crear factura en gigstack
    const factura = await gigstack.invoices.create({
      tipo: 'I', // Ingreso
      receptor: {
        rfc: rfc,
        nombre: razon_social,
        uso_cfdi: uso_cfdi || 'G03', // Default: Gastos en general
        domicilio_fiscal_receptor: '01234' // Requerido desde 2026
      },
      conceptos: items,
      forma_pago: metodo_pago || '03', // Transferencia electrónica
      metodo_pago: 'PUE', // Pago en una exhibición
      moneda: 'MXN',
      external_id: paymentIntent.id // Vincular con Stripe
    });

    console.log('✅ Factura generada:', factura.uuid);
    
    // Enviar factura por email automáticamente
    await gigstack.invoices.sendEmail(factura.id, {
      to: email,
      subject: '📄 Tu factura de gigstack',
      template: 'default'
    });

    return factura;

  } catch (error) {
    console.error('❌ Error al facturar:', error.message);
    // Implementar retry logic o notificación a equipo
    await notificarErrorFacturacion(paymentIntent, error);
    throw error;
  }
}

Paso 4: Incluir RFC en el Checkout de Stripe

Para que esto funcione, necesitas capturar el RFC del cliente antes de procesar el pago. Agrega estos campos a tu checkout:

// Frontend: Capturar RFC en el checkout
const paymentIntent = await stripe.paymentIntents.create({
  amount: 50000, // $500 MXN
  currency: 'mxn',
  description: 'Plan Pro - Mes de Enero 2026',
  metadata: {
    rfc: 'XAXX010101000',
    email: 'cliente@ejemplo.com',
    razon_social: 'Empresa Ejemplo SA de CV',
    uso_cfdi: 'G03',
    metodo_pago: '03'
  }
});

Paso 5: Manejo de Errores del SAT

El SAT puede rechazar facturas por múltiples razones. Implementa un sistema robusto de manejo de errores:

async function notificarErrorFacturacion(paymentIntent, error) {
  // Clasificar tipo de error
  const esErrorSAT = error.code?.startsWith('SAT_');
  const esErrorRFC = error.message?.includes('RFC');
  
  if (esErrorRFC) {
    // RFC inválido: notificar al cliente para corrección
    await enviarEmailCorreccionRFC(paymentIntent);
  } else if (esErrorSAT) {
    // Error del SAT: reintentar después
    await agendarReintento(paymentIntent, error);
  } else {
    // Error desconocido: alertar al equipo técnico
    await alertarEquipoTecnico(paymentIntent, error);
  }
}

async function agendarReintento(paymentIntent, error) {
  // Usar cron job o queue (Bull, BeeQueue, etc.)
  await queue.add('retry-invoice', {
    paymentIntent: paymentIntent.id,
    intentos: 1,
    error: error.message
  }, {
    delay: 5 * 60 * 1000, // Reintentar en 5 minutos
    attempts: 3,
    backoff: {
      type: 'exponential',
      delay: 5000
    }
  });
}

Paso 6: Testing en Sandbox

Antes de ir a producción, prueba todo en el entorno de sandbox de gigstack:

// Configuración para testing
const gigstackTest = new GigstackClient({
  apiKey: process.env.GIGSTACK_TEST_API_KEY,
  endpoint: 'https://sandbox.gigstack.io/v1',
  sandbox: true
});

// RFCs de prueba del SAT
const RFC_PRUEBA = 'EKU9003173C9'; // RFC genérico para testing

// Usar Stripe test mode
const stripeTest = require('stripe')(process.env.STRIPE_TEST_KEY);

Mejores Prácticas 2026

  1. Validación previa de RFC: Usa el endpoint de gigstack /validate-rfc antes del checkout
  2. Idempotencia: Usa external_id para evitar facturas duplicadas
  3. Logging completo: Registra cada evento de Stripe y cada llamada a gigstack
  4. Rate limiting: gigstack permite 100 req/min, implementa throttling si procesas alto volumen
  5. Webhooks resilientes: Implementa retry logic con backoff exponencial

Monitoreo y Debugging

Implementa logs estructurados para trackear el flujo completo:

const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'invoicing-errors.log', level: 'error' }),
    new winston.transports.File({ filename: 'invoicing-combined.log' })
  ]
});

logger.info('Factura creada', {
  stripe_payment_id: paymentIntent.id,
  gigstack_invoice_id: factura.id,
  uuid: factura.uuid,
  rfc: factura.receptor.rfc,
  monto: paymentIntent.amount / 100,
  timestamp: new Date().toISOString()
});

Recursos y Documentación

FAQ Técnica

1. ¿Qué hago si el webhook de Stripe no llega a mi servidor?

Respuesta: Verifica que tu endpoint esté accesible públicamente (usa ngrok en desarrollo), confirma que la URL esté correctamente configurada en el dashboard de Stripe, y revisa que estés usando express.raw() en lugar de express.json() para validar la firma del webhook. Stripe necesita el body raw para verificar la autenticidad.

2. ¿Cómo manejo facturas cuando el cliente proporciona un RFC inválido después del pago?

Respuesta: Implementa un flujo de corrección: (1) Guarda el pago como "pendiente de facturar" en tu base de datos, (2) Envía un email al cliente con un link para actualizar su RFC, (3) Cuando corrija el RFC, dispara la facturación manualmente con gigstack.invoices.create(). Usa external_id para vincular con el payment_intent original.

3. ¿gigstack soporta cancelación de facturas si hay un reembolso en Stripe?

Respuesta: Sí. Escucha el evento charge.refunded de Stripe y usa gigstack.invoices.cancel(invoice_id, { motivo: '01', uuid_replacement: null }). El motivo '01' indica "Comprobante emitido con errores con relación". Si generas una nota de crédito, incluye el uuid_replacement del nuevo comprobante.

4. ¿Cuál es el límite de rate limiting de gigstack API en 2026?

Respuesta: gigstack permite 100 requests por minuto en planes estándar y 500 req/min en planes enterprise. Si procesas alto volumen, implementa un sistema de queue (Bull, RabbitMQ) para distribuir las llamadas y evitar errores 429. El SDK de Node.js incluye retry automático con backoff exponencial desde la versión 2.1.0.

Conclusión

Integrar Stripe con gigstack elimina completamente la carga manual de facturación. Con este código base, tienes un sistema robusto que maneja pagos, genera facturas automáticamente, y entrega comprobantes fiscales sin intervención humana.

Recuerda probar exhaustivamente en sandbox antes de ir a producción, y monitorea tus logs para identificar problemas temprano.

¿Necesitas ayuda con la implementación? Revisa la documentación completa de gigstack o contacta al equipo técnico.

Blogs que te pueden gustar