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
- 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). - Prueba en beta: tu cuenta empieza en el ambiente de homologación de SUNAT: emisiones reales de punta a punta, pero sin validez tributaria.
- Emite tu primer comprobante (abajo el ejemplo) o usa el portal web sin escribir código.
- 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)
}- El correlativo lo asigna el servicio de forma atómica: no lo envíes; evita duplicados y saltos ante reintentos.
- Facturas (01): el cliente debe ser RUC (tipoDoc 6). La forma de pago Contado se informa automáticamente; para crédito con cuotas envía
formaPago. - Campos opcionales:
fechaEmision(ISO),totalExoneradas,totalInafectas,serviceCharge(recargo al consumo).
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:
| Documento | Mecanismo | Qué 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
| Endpoint | Devuelve |
|---|---|
GET /me | Datos de tu cuenta emisora (RUC, ambiente, total emitido). |
GET /comprobantes | Tus comprobantes (número, cliente, importe, estado, fecha) — últimos 200. |
GET /comprobantes/:id | Detalle completo: líneas, montos, hash, historial de eventos SUNAT (con tickets de anulación). |
GET /comprobantes/:id/download?type=pdf | Representación impresa A4 con código QR oficial SUNAT. |
GET /comprobantes/:id/download?type=xml | XML UBL 2.1 firmado (el documento legal). |
GET /comprobantes/:id/download?type=cdr | Constancia de recepción de SUNAT (zip). |
GET /stats | Métricas: totales, montos facturados, por tipo/estado/día, actividad reciente. |
Catálogos SUNAT
Tipos de comprobante (catálogo 01)
| Código | Documento | Serie sugerida |
|---|---|---|
| 01 | Factura | F001 |
| 03 | Boleta de venta | B001 |
| 07 | Nota de crédito | FC01 (de factura) / BC01 (de boleta) |
| 08 | Nota de débito | FD01 / BD01 |
Documento de identidad del cliente (catálogo 06)
| Código | Documento |
|---|---|
| 0 | Sin documento (venta menor a S/ 700) |
| 1 | DNI |
| 4 | Carnet de extranjería |
| 6 | RUC (obligatorio en facturas) |
| 7 | Pasaporte |
Motivos de nota de crédito (catálogo 09)
| Código | Motivo |
|---|---|
| 01 | Anulación de la operación |
| 02 | Anulación por error en el RUC |
| 03 | Corrección por error en la descripción |
| 06 | Devolución total |
| 07 | Devolución por ítem |
| 09 | Disminución en el valor |
Motivos de nota de débito (catálogo 10)
| Código | Motivo |
|---|---|
| 01 | Intereses por mora |
| 02 | Aumento en el valor |
| 03 | Penalidades / otros conceptos |
Estados del comprobante
| Estado | Significado |
|---|---|
| aceptado | SUNAT emitió CDR de conformidad. El comprobante es válido. |
| observado | Aceptado con observaciones: revisa el detalle, puede requerir corrección futura. |
| rechazado | SUNAT lo rechazó. No tiene validez: corrige el dato y emite de nuevo (el número no se reutiliza). |
| pendiente | Firmado pero aún no confirmado por SUNAT (contingencia). Se reintenta solo. |
| anulando | Anulación enviada; el ticket de SUNAT aún está en proceso. |
| anulado | Baja (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:
| Evento | Cuándo |
|---|---|
comprobante.emitido | Al emitir (aceptado, observado o rechazado). |
comprobante.anulado | Al 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ón | Qué hace el sistema | Qué haces tú |
|---|---|---|
| SUNAT caído / no responde | Guarda 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 local | La 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 vencer | Aviso 30 días antes. | Renuevas el .pfx y lo subes en el panel. |
| Clave SOL incorrecta | El botón "Verificar conexión" lo detecta sin emitir. | Corriges la clave en el panel. |
| Comprobante rechazado | No pierde el número: se reutiliza. | Corriges el dato (motivo en el detalle) y vuelves a emitir. |
| Impresora falla | El 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ón | Causa y solución |
|---|---|
| HTTP 401 | Clave de API inválida, incompleta o desactivada. Verifica el header Authorization. |
| Rechazo 2800/2801 | Documento del cliente inválido (DNI de 8 dígitos, RUC de 11). En facturas el cliente debe ser RUC. |
| Rechazo por montos | La suma de líneas no cuadra con los totales: totalGravadas = suma de valorVenta; importeTotal = totalGravadas + totalIgv. Redondea a 2 decimales. |
| Serie inválida | Boletas empiezan con B, facturas con F, NC con BC/FC, ND con BD/FD (4 caracteres). |
| "en proceso" al anular | SUNAT no resolvió el ticket dentro de la solicitud. El comprobante queda "anulando"; vuelve a consultar el detalle más tarde. |
| Nota sin ref | Las notas (07/08) requieren ref {tipoDoc, serie, correlativo} del documento afectado y motivoCodigo. |
Ambientes
| Ambiente | Para qué | Validez |
|---|---|---|
| beta (homologación) | Desarrollo y pruebas de integración contra el SUNAT beta real. | Sin validez tributaria. |
| producción | Operació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.