Volver al Blog
SoftwareDesarrolloE-commerce

Facturación Electrónica SUNAT: Cómo Integrar Comprobantes en Apps Web y E-commerce

Brayan Developer
5 min de lectura
Facturación Electrónica SUNAT: Cómo Integrar Comprobantes en Apps Web y E-commerce
Aprende a integrar facturación electrónica SUNAT (Boletas, Facturas y Notas de Crédito) en aplicaciones web y tiendas virtuales con Next.js, APIs REST y Webhooks.

La emisión automática de comprobantes de pago electrónicos es un requisito indispensable para cualquier negocio digital y tienda online en Perú. En esta guía exploramos la arquitectura técnica para conectar Next.js y pasarelas de pago con proveedores PSE/OSE y la API de SUNAT.

Portada

El reto de la Facturación Electrónica en el Comercio Digital#

Para cualquier empresa o plataforma de comercio electrónico en el Perú, emitir comprobantes de pago (Facturas, Boletas de Venta, Notas de Crédito y Débito) en tiempo real no solo es una exigencia tributaria de la SUNAT, sino también un factor crítico para la confianza del cliente y la automatización contable.

El flujo tradicional de facturación manual genera retrasos, errores humanos en el cálculo del IGV o retenciones, y reclamos de clientes que no reciben su archivo XML y representación impresa en PDF de forma inmediata tras el checkout.

Integrar un sistema de facturación electrónica automatizado permite:

  • Emisión instantánea tras la confirmación del pago en la pasarela (Niubiz, Culqi, Mercado Pago o Stripe).
  • Validación y firma digital del XML conforme a los estándares UBL 2.1 exigidos por SUNAT.
  • Generación y envío automático del PDF y XML al correo del cliente y al panel de administración.
  • Sincronización con ERPs o bases de datos para control de inventario y balances fiscales.

Arquitectura de Integración: Next.js + API de Facturación (PSE / OSE)#

Existen dos vías para conectarse a SUNAT: vía directa mediante Servicios Web SOAP (requiere certificado digital propio y homologación compleja) o mediante un Proveedor de Servicios Electrónicos (PSE/OSE) con API REST (enfoque más rápido, seguro y escalable para aplicaciones modernas).

El siguiente diagrama resume el flujo de eventos tras una compra:

  1. El usuario completa el pago en la tienda Next.js.
  2. La pasarela de pago dispara un Webhook al endpoint /api/webhooks/payment de Next.js.
  3. El servidor valida la firma del webhook y extrae los datos fiscales (RUC/DNI, Razón Social, Ítems, Moneda, Descuentos).
  4. Se ejecuta una petición POST al servicio PSE/OSE con la estructura JSON del comprobante.
  5. El proveedor firma el XML con certificado digital, lo envía a SUNAT/OSE y devuelve el CDR (Constancia de Recepción), el hash y los enlaces a los archivos PDF y XML.
  6. La aplicación almacena el comprobante en Supabase/PostgreSQL y notifica al cliente vía Email/WhatsApp.

Implementación de un Endpoint de Emisión en Next.js (App Router)#

A continuación se muestra un ejemplo de implementación de un Route Handler seguro en Next.js para emitir una Factura o Boleta electrónica:

// src/app/api/invoices/issue/route.ts
import { NextRequest, NextResponse } from "next/server";

interface InvoiceItem {
  description: string;
  quantity: number;
  unitPrice: number; // Precio con IGV
}

interface InvoiceRequest {
  tipoDoc: "01" | "03"; // 01: Factura, 03: Boleta
  clienteDocTipo: "6" | "1"; // 6: RUC, 1: DNI
  clienteDocNumero: string;
  clienteNombre: string;
  clienteEmail: string;
  items: InvoiceItem[];
}

export async function POST(req: NextRequest) {
  try {
    const body: InvoiceRequest = await req.json();

    // 1. Validaciones básicas de integridad
    if (!body.clienteDocNumero || !body.items?.length) {
      return NextResponse.json({ error: "Datos fiscales incompletos" }, { status: 400 });
    }

    // 2. Cálculo de base imponible e IGV (18%)
    const total = body.items.reduce((acc, item) => acc + item.quantity * item.unitPrice, 0);
    const subtotal = Number((total / 1.18).toFixed(2));
    const igv = Number((total - subtotal).toFixed(2));

    // 3. Payload estandarizado UBL 2.1 para la API de Facturación
    const payload = {
      tipo_de_comprobante: body.tipoDoc === "01" ? 1 : 2,
      serie: body.tipoDoc === "01" ? "F001" : "B001",
      cliente_tipo_de_documento: body.clienteDocTipo,
      cliente_numero_de_documento: body.clienteDocNumero,
      cliente_denominacion: body.clienteNombre,
      cliente_email: body.clienteEmail,
      total_gravada: subtotal,
      total_igv: igv,
      total: total,
      items: body.items.map((item) => ({
        descripcion: item.description,
        cantidad: item.quantity,
        valor_unitario: Number((item.unitPrice / 1.18).toFixed(4)),
        precio_unitario: item.unitPrice,
        igv: Number((item.quantity * (item.unitPrice - item.unitPrice / 1.18)).toFixed(2)),
        total: Number((item.quantity * item.unitPrice).toFixed(2)),
      })),
    };

    // 4. Envío a la API del PSE
    const response = await fetch(`${process.env.INVOICE_API_URL}/documents`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${process.env.INVOICE_API_TOKEN}`,
      },
      body: JSON.stringify(payload),
    });

    const data = await response.json();

    if (!response.ok || !data.success) {
      console.error("Error al emitir comprobante SUNAT:", data);
      return NextResponse.json({ error: "Fallo en la emisión electrónica" }, { status: 502 });
    }

    return NextResponse.json({
      success: true,
      serieNumero: data.numero_comprobante,
      pdfUrl: data.enlace_del_pdf,
      xmlUrl: data.enlace_del_xml,
      cdrResponse: data.sunat_response,
    });
  } catch (error) {
    console.error("Error interno en emisión de comprobantes:", error);
    return NextResponse.json({ error: "Error interno del servidor" }, { status: 500 });
  }
}

Buenas Prácticas de Resiliencia y Control de Errores#

Al integrar facturación electrónica en entornos de alta concurrencia, es fundamental aplicar las siguientes prácticas de ingeniería:

  1. Colas de Procesamiento Asíncrono (Job Queues): Si la API de SUNAT o del PSE presenta latencia temporal, nunca debes bloquear la respuesta al usuario final. Almacena la transacción como pendiente_facturacion y utiliza un worker en segundo plano (vía BullMQ o Cron en Next.js) con reintentos automáticos (exponential backoff).

  2. Idempotencia en la Creación de Comprobantes: Evita la doble emisión de facturas ante reintentos de webhooks utilizando una clave de idempotencia (order_id o payment_intent_id) indexada como única en tu base de datos.

  3. Validación Previa de RUC y DNI: Integra una consulta previa a servicios de validación de padrón SUNAT/RENIEC para autocompletar la razón social y comprobar que el RUC se encuentre en estado ACTIVO y condición HABIDO.


¿Necesitas Automatizar la Facturación de tu Empresa o Tienda?#

Una integración adecuada de facturación electrónica ahorra cientos de horas administrativas al mes y garantiza el cumplimiento tributario sin fricción.

Si deseas implementar facturación electrónica a medida para tu sistema ERP, plataforma SaaS o tienda online en Perú, contáctanos hoy mismo o revisa nuestros servicios de desarrollo de software para analizar tu requerimiento técnico.

Etiquetas
Facturación ElectrónicaSUNATNext.jsAPIs RESTE-commerce PerúSoftware a Medida
Compartir:XLinkedInWhatsApp

¿Te gustaría profundizar en estos temas?

Aprende sobre desarrollo de software, apps a medida, automatizaciones con N8N, Next.js y Cloud con casos reales.

Hablemos