← Inicio

Documentación de la API

Facturación electrónica SUNAT (SEE — Del Contribuyente) como servicio. Emisión de boletas, facturas y notas con firma digital XML-DSig, envío directo a SUNAT y CDR, en una API REST. Base URL: https://factura.loyfixds.com/api/v1.

Inicio rápido

  1. Alta del emisor: el administrador registra tu RUC con tu certificado digital (.pfx) y usuario secundario SOL, y te entrega tu clave de API (fk_…, se muestra una sola vez).
  2. Prueba en beta: tu cuenta empieza en el ambiente de homologación de SUNAT: emisiones reales de punta a punta, pero sin validez tributaria.
  3. Emite tu primer comprobante (abajo el ejemplo) o usa el portal web sin escribir código.
  4. Pasa a producción: cuando tu integración esté lista, el administrador cambia tu ambiente y tus comprobantes pasan a tener validez legal.

Autenticación

Todas las llamadas llevan tu clave de API en el header Authorization:

Authorization: Bearer fk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

La clave identifica a tu empresa (RUC emisor): no necesitas enviar tu RUC ni certificados en cada solicitud; el servicio custodia tu certificado cifrado (AES-256-GCM) y firma por ti. Verifica tu cuenta con GET /api/v1/me.

Emitir boleta o factura

POST /api/v1/comprobantes — el envío a SUNAT es inmediato; la respuesta incluye el CDR.

curl -X POST https://factura.loyfixds.com/api/v1/comprobantes \
  -H "Authorization: Bearer TU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tipoDoc": "03",              // 03=boleta, 01=factura
    "serie": "B001",              // B*** para boletas, F*** para facturas
    "moneda": "PEN",
    "cliente": {
      "tipoDoc": "1",             // 1=DNI, 6=RUC (obligatorio en facturas), 0=sin doc
      "numDoc": "12345678",
      "nombre": "JUAN PEREZ"
    },
    "lineas": [{
      "descripcion": "Producto de ejemplo",
      "cantidad": 1,
      "valorUnitario": 8.47,      // precio SIN IGV
      "precioUnitario": 10.00,    // precio CON IGV
      "valorVenta": 8.47,         // valorUnitario × cantidad
      "igv": 1.53,
      "tasaIgv": 18,
      "afectacion": "gravado"
    }],
    "totalGravadas": 8.47,
    "totalIgv": 1.53,
    "totalDescuentos": 0,
    "importeTotal": 10.00
  }'

Respuesta:

{
  "fullNumber": "B001-00000005",
  "correlativo": 5,               // lo asigna el servicio (correlativo transaccional)
  "estado": "aceptado",
  "hash": "2cd5a302c6c7…",        // resumen del XML firmado
  "observaciones": ["La Boleta numero B001-00000005, ha sido aceptada"],
  "cdrBase64": "UEsDBBQ…"         // constancia de recepción de SUNAT (zip)
}

Notas de crédito (07) y débito (08)

Mismo endpoint, agregando el documento afectado y el motivo:

{
  "tipoDoc": "07",                       // 07=NC, 08=ND
  "serie": "BC01",                       // BC/FC para NC, BD/FD para ND
  "motivoCodigo": "01",                  // catálogo 09 (NC) o 10 (ND) — ver abajo
  "motivoDescripcion": "Anulación de la operación",
  "ref": { "tipoDoc": "03", "serie": "B001", "correlativo": 4 },
  "cliente": { … }, "lineas": [ … ],     // igual que una emisión normal
  "totalGravadas": …, "totalIgv": …, "importeTotal": …
}

Anular comprobantes

POST /api/v1/comprobantes/:id/baja con { "motivo": "…" }. El servicio elige el mecanismo correcto según SUNAT:

DocumentoMecanismoQué pasa
Factura (01)Comunicación de baja (RA)Se envía por ticket; en segundos SUNAT confirma y el comprobante queda "anulado".
Boleta (03)Resumen diario (RC, condición 3)Mismo flujo por ticket; la boleta queda "anulada".
NC / ND— (no se anulan)Se corrigen emitiendo otra nota.

Si SUNAT demora el ticket, el comprobante queda en estado anulando y la respuesta trae el ticket para seguimiento. Los anulados dejan de sumar a tu facturación.

Consultas y descargas

EndpointDevuelve
GET /meDatos de tu cuenta emisora (RUC, ambiente, total emitido).
GET /comprobantesTus comprobantes (número, cliente, importe, estado, fecha) — últimos 200.
GET /comprobantes/:idDetalle completo: líneas, montos, hash, historial de eventos SUNAT (con tickets de anulación).
GET /comprobantes/:id/download?type=pdfRepresentación impresa A4 con código QR oficial SUNAT.
GET /comprobantes/:id/download?type=xmlXML UBL 2.1 firmado (el documento legal).
GET /comprobantes/:id/download?type=cdrConstancia de recepción de SUNAT (zip).
GET /statsMétricas: totales, montos facturados, por tipo/estado/día, actividad reciente.

Catálogos SUNAT

Tipos de comprobante (catálogo 01)

CódigoDocumentoSerie sugerida
01FacturaF001
03Boleta de ventaB001
07Nota de créditoFC01 (de factura) / BC01 (de boleta)
08Nota de débitoFD01 / BD01

Documento de identidad del cliente (catálogo 06)

CódigoDocumento
0Sin documento (venta menor a S/ 700)
1DNI
4Carnet de extranjería
6RUC (obligatorio en facturas)
7Pasaporte

Motivos de nota de crédito (catálogo 09)

CódigoMotivo
01Anulación de la operación
02Anulación por error en el RUC
03Corrección por error en la descripción
06Devolución total
07Devolución por ítem
09Disminución en el valor

Motivos de nota de débito (catálogo 10)

CódigoMotivo
01Intereses por mora
02Aumento en el valor
03Penalidades / otros conceptos

Estados del comprobante

EstadoSignificado
aceptadoSUNAT emitió CDR de conformidad. El comprobante es válido.
observadoAceptado con observaciones: revisa el detalle, puede requerir corrección futura.
rechazadoSUNAT lo rechazó. No tiene validez: corrige el dato y emite de nuevo (el número no se reutiliza).
pendienteFirmado pero aún no confirmado por SUNAT (contingencia). Se reintenta solo.
anulandoAnulación enviada; el ticket de SUNAT aún está en proceso.
anuladoBaja (RA) o anulación por resumen (RC) aceptada por SUNAT.

Webhooks

Configura una URL (PUT /api/v1/me/webhook o desde el portal, pestaña API) y el servicio te notifica cada evento con un POST JSON:

EventoCuándo
comprobante.emitidoAl emitir (aceptado, observado o rechazado).
comprobante.anuladoAl resolverse una anulación (RA/RC), incluso si el ticket demoró.
POST https://tu-sistema.com/webhooks/facturacion
X-Fact-Event: comprobante.emitido
X-Fact-Signature: sha256=3f5a8c…        // HMAC-SHA256(secret, body)

{
  "event": "comprobante.emitido",
  "timestamp": "2026-07-06T21:15:00.000Z",
  "data": {
    "tipoDoc": "03",
    "fullNumber": "B001-00000006",
    "estado": "aceptado",
    "importeTotal": 10,
    "moneda": "PEN",
    "cliente": { "tipoDoc": "1", "numDoc": "12345678", "nombre": "JUAN PEREZ" },
    "hash": "2cd5a302…",
    "observaciones": ["La Boleta numero B001-00000006, ha sido aceptada"]
  }
}

Verifica la firma: calcula HMAC-SHA256(secret, body_crudo) y compáralo con X-Fact-Signature (tras el prefijo sha256=). El secret se entrega una sola vez al configurar la URL. El servicio reintenta una vez si tu endpoint falla; responde 2xx rápido y procesa de forma asíncrona. Para probar sin un endpoint propio: /api/v1/webhook-test.

Contingencia — ¿y si SUNAT se cae?

En SEE Del Contribuyente, el comprobante es válido desde que se emite y se firma; el CDR de SUNAT es una confirmación, no un requisito. Por eso una caída de SUNAT nunca detiene una venta: emites, entregas el ticket, y el sistema informa a SUNAT después.

SituaciónQué hace el sistemaQué haces tú
SUNAT caído / no respondeGuarda el comprobante como "pendiente" (ya firmado) y reintenta cada 10 min hasta que SUNAT vuelve.Nada. Sigues vendiendo; el cliente recibe su ticket igual.
Internet caído en el localLa API está en la nube y necesita conexión.Registras la venta y emites al reconectar (factura: hasta 3 días de plazo). Ideal: internet de respaldo.
Certificado por vencerAviso 30 días antes.Renuevas el .pfx y lo subes en el panel.
Clave SOL incorrectaEl botón "Verificar conexión" lo detecta sin emitir.Corriges la clave en el panel.
Comprobante rechazadoNo pierde el número: se reutiliza.Corriges el dato (motivo en el detalle) y vuelves a emitir.
Impresora fallaEl comprobante ya es válido aunque no se imprima.Reimprimes el ticket o envías el PDF/QR.

Facturas: tienes 3 días calendario (desde el día siguiente a la emisión) para informarlas a SUNAT. El sistema reenvía los "pendiente" automáticamente dentro de ese plazo, así que una caída típica de SUNAT (minutos u horas) se resuelve sola. La base se respalda a diario.

Errores comunes

SituaciónCausa y solución
HTTP 401Clave de API inválida, incompleta o desactivada. Verifica el header Authorization.
Rechazo 2800/2801Documento del cliente inválido (DNI de 8 dígitos, RUC de 11). En facturas el cliente debe ser RUC.
Rechazo por montosLa suma de líneas no cuadra con los totales: totalGravadas = suma de valorVenta; importeTotal = totalGravadas + totalIgv. Redondea a 2 decimales.
Serie inválidaBoletas empiezan con B, facturas con F, NC con BC/FC, ND con BD/FD (4 caracteres).
"en proceso" al anularSUNAT no resolvió el ticket dentro de la solicitud. El comprobante queda "anulando"; vuelve a consultar el detalle más tarde.
Nota sin refLas notas (07/08) requieren ref {tipoDoc, serie, correlativo} del documento afectado y motivoCodigo.

Ambientes

AmbientePara quéValidez
beta (homologación)Desarrollo y pruebas de integración contra el SUNAT beta real.Sin validez tributaria.
producciónOperación real con tu certificado digital vigente.Validez legal plena.

El cambio de ambiente lo gestiona el administrador del servicio (requiere tu certificado de producción). La API y tus series no cambian.