Skip to main content

Introducción

Las series son códigos alfanuméricos que identifican el tipo de comprobante y el punto de emisión. Cada comprobante electrónico en Perú debe tener una serie única y un número correlativo secuencial.
La correcta configuración de las series es fundamental para cumplir con las normas de SUNAT y evitar rechazos al enviar comprobantes.

¿Qué es una Serie?

Una serie es un código de 4 caracteres que identifica:
  • El tipo de comprobante (primera letra)
  • El punto de emisión o sucursal (números)
Formato estándar: LNNN
  • L: Letra que identifica el tipo de documento
  • NNN: Tres dígitos numéricos (generalmente 001)
Ejemplo completo de comprobante: F001-00000123
  • Serie: F001
  • Número correlativo: 00000123

Tipos de Series SUNAT

Series para Comprobantes de Venta

  • Formato: F001, F002, F003
  • Primera letra: Siempre F
  • Uso: Facturas electrónicas a clientes con RUC
  • Código SUNAT: 01
  • Numeración: Correlativa desde 1
  • Ejemplo: F001-00000001, F001-00000002, F001-00000003
  • Formato: B001, B002, B003
  • Primera letra: Siempre B
  • Uso: Boletas de venta a consumidores finales (DNI/CE)
  • Código SUNAT: 03
  • Numeración: Correlativa desde 1
  • Ejemplo: B001-00000001, B001-00000002, B001-00000003
  • Observación: Requieren Resumen Diario para validación SUNAT
Para Facturas:
  • Formato: FC01, FC02, FC03
  • Primera letra: FC (4 caracteres en total)
  • Código SUNAT: 07
  • Uso: Anulación o corrección de facturas
Para Boletas:
  • Formato: BC01, BC02, BC03
  • Primera letra: BC
  • Código SUNAT: 07
  • Uso: Anulación o corrección de boletas
Ejemplo: FC01-00000001 (nota de crédito de la factura F001-00000050)
Para Facturas:
  • Formato: FD01, FD02, FD03
  • Código SUNAT: 08
  • Uso: Incremento en el monto de facturas
Para Boletas:
  • Formato: BD01, BD02, BD03
  • Código SUNAT: 08
  • Uso: Incremento en el monto de boletas
  • Formato: T001, T002, T003
  • Primera letra: T (de “Traslado”)
  • Código SUNAT: 09
  • Uso: Guías de remisión remitente
  • Numeración: Correlativa desde 1
  • Ejemplo: T001-00000001
  • Formato: V001, V002, V003
  • Primera letra: V (de “Vehículo”)
  • Código SUNAT: 31
  • Uso: Guías de remisión del transportista
  • Ejemplo: V001-00000001

Series Internas (No SUNAT)

  • Formato: NV01, NV02, NV03
  • Código interno: 06 (en el sistema Santo Domingo, id_tido=6)
  • Uso: Documento interno sin valor tributario
  • No se envía a SUNAT
  • Descuenta stock del Almacén 2 (Kardex Real)
  • Puede convertirse en Boleta o Factura después
  • Ejemplo: NV01-00000001

Numeración Correlativa

¿Qué es el Correlativo?

El correlativo es el número secuencial que se asigna a cada comprobante dentro de una serie. Características:
  • Empieza en 1 (o el número que configures)
  • Se incrementa en 1 por cada nuevo comprobante
  • No puede haber saltos ni duplicados
  • Se formatea con ceros a la izquierda: 00000001, 00000002, etc.

Formato del Correlativo

  • Longitud: Generalmente 8 dígitos con padding de ceros
  • Ejemplos:
    • 00000001 - Primer comprobante
    • 00000099 - Comprobante 99
    • 00001234 - Comprobante 1,234
    • 00012345 - Comprobante 12,345
Importante: Una vez que envías un número correlativo a SUNAT, no puedes reutilizarlo. Si un comprobante es rechazado, debes anularlo y crear uno nuevo con el siguiente correlativo.

Configuración en Santo Domingo

Tabla: documentos_empresas

El sistema usa la tabla documentos_empresas para gestionar series y correlativos:
CREATE TABLE documentos_empresas (
  id_empresa INT,
  id_tido INT,          -- Tipo de documento (1=Boleta, 2=Factura, etc.)
  serie VARCHAR(4),     -- Serie (F001, B001, T001, etc.)
  numero INT,           -- Último correlativo usado
  PRIMARY KEY (id_empresa, id_tido, serie)
);
Ejemplo de datos:
id_empresaid_tidoserienumero
12F001125
11B001543
16NV0189
19T00145
Esto significa que:
  • La próxima factura será F001-00000126
  • La próxima boleta será B001-00000544
  • La próxima nota de venta será NV01-00000090
  • La próxima guía será T001-00000046

Flujo de Asignación de Correlativo

Cuando creas una nueva venta, el sistema:
1

Consulta el último número usado

$ultimaVenta = Venta::where('id_empresa', $user->id_empresa)
    ->where('serie', $validated['serie'])
    ->max('numero') ?? 0;
Busca el número más alto en la tabla ventas para esa serie.
2

Consulta el número base configurado

$numeroBase = DB::table('documentos_empresas')
    ->where('id_empresa', $user->id_empresa)
    ->where('serie', $validated['serie'])
    ->value('numero') ?? 0;
Obtiene el número configurado en documentos_empresas.
3

Calcula el próximo número

$proximoNumero = max($ultimaVenta, $numeroBase) + 1;
Toma el mayor entre:
  • El último número usado en ventas
  • El número base configurado
Y le suma 1.
4

Sincroniza documentos_empresas

DB::table('documentos_empresas')
    ->where('id_empresa', $user->id_empresa)
    ->where('serie', $validated['serie'])
    ->update(['numero' => $proximoNumero]);
Actualiza el contador en documentos_empresas con el nuevo número.
5

Crea la venta con el correlativo

$venta = Venta::create([
    'serie' => $validated['serie'],
    'numero' => $proximoNumero,
    // ... otros campos
]);
Guarda la venta con el número correlativo asignado.
Referencia: app/Http/Controllers/VentasController.php, líneas 181-198

Endpoint: Obtener Próximo Número

El sistema tiene un endpoint para consultar el siguiente correlativo sin crear una venta: Request:
GET /api/ventas/proximo-numero?serie=F001
Authorization: Bearer {token}
Response:
{
  "success": true,
  "numero": 126,
  "numero_completo": "F001-00000126"
}
Referencia: app/Http/Controllers/VentasController.php, líneas 604-634

Cómo Configurar una Nueva Serie

1

Decidir el código de serie

Según el tipo de comprobante:
  • Facturas: F001, F002, F003
  • Boletas: B001, B002, B003
  • Guías: T001, T002, T003
  • Notas de venta: NV01, NV02, NV03
Si tienes múltiples sucursales o puntos de venta, usa series diferentes para cada uno:
  • Sucursal 1: F001, B001
  • Sucursal 2: F002, B002
  • Sucursal 3: F003, B003
2

Insertar en documentos_empresas

Conéctate a la base de datos y ejecuta:
INSERT INTO documentos_empresas 
  (id_empresa, id_tido, serie, numero) 
VALUES 
  (1, 2, 'F001', 0);  -- Factura
Valores de id_tido:
  • 1 = Boleta
  • 2 = Factura
  • 6 = Nota de Venta
  • 7 = Nota de Crédito
  • 8 = Nota de Débito
  • 9 = Guía de Remisión
  • 31 = Guía de Remisión Transportista
Campo numero:
  • Usa 0 si quieres empezar desde 00000001
  • Usa 1000 si quieres empezar desde 00001001 (útil si migras de otro sistema)
3

Verificar en el sistema

  1. Ve al módulo de Ventas
  2. Haz clic en Nueva Venta
  3. Selecciona el tipo de comprobante (Boleta, Factura, etc.)
  4. El sistema debe mostrar automáticamente:
    • La serie correcta (F001, B001, etc.)
    • El próximo número disponible
Si no aparece, verifica que el registro en documentos_empresas tenga el id_tido correcto.

Cambiar el Número de Inicio

Si necesitas iniciar la numeración desde un número específico (ej. al migrar de otro sistema):
1

Actualizar numero base

UPDATE documentos_empresas 
SET numero = 500
WHERE id_empresa = 1 
  AND serie = 'F001';
Esto hará que la próxima factura sea F001-00000501.
2

Verificar que no hay conflictos

Asegúrate de que no existan ventas con números mayores:
SELECT MAX(numero) 
FROM ventas 
WHERE id_empresa = 1 
  AND serie = 'F001';
Si el resultado es 600 y configuras el numero base en 500, el sistema usará 601 (el mayor de ambos).
No cambies el numero base si ya enviaste comprobantes a SUNAT con esa serie. Esto puede causar duplicados y rechazos.

Series para Múltiples Puntos de Venta

Si tu negocio tiene varias sucursales o cajas:
1

Asignar series diferentes

  • Sucursal 1 - Caja 1: F001, B001
  • Sucursal 1 - Caja 2: F002, B002
  • Sucursal 2 - Caja 1: F003, B003
  • Sucursal 2 - Caja 2: F004, B004
2

Configurar en documentos_empresas

INSERT INTO documentos_empresas (id_empresa, id_tido, serie, numero) VALUES
  (1, 2, 'F001', 0),  -- Sucursal 1 - Caja 1 - Facturas
  (1, 1, 'B001', 0),  -- Sucursal 1 - Caja 1 - Boletas
  (1, 2, 'F002', 0),  -- Sucursal 1 - Caja 2 - Facturas
  (1, 1, 'B002', 0),  -- Sucursal 1 - Caja 2 - Boletas
  (1, 2, 'F003', 0),  -- Sucursal 2 - Caja 1 - Facturas
  (1, 1, 'B003', 0);  -- Sucursal 2 - Caja 1 - Boletas
3

Asignar series a usuarios (opcional)

Puedes modificar el sistema para que cada usuario tenga asignada una serie específica:Opción 1: Agregar campos a la tabla users
ALTER TABLE users ADD COLUMN serie_factura VARCHAR(4) DEFAULT 'F001';
ALTER TABLE users ADD COLUMN serie_boleta VARCHAR(4) DEFAULT 'B001';
Opción 2: Crear una tabla usuarios_series
CREATE TABLE usuarios_series (
  id_usuario INT,
  id_tido INT,
  serie VARCHAR(4),
  PRIMARY KEY (id_usuario, id_tido)
);
Luego modificar el formulario de ventas para que use la serie asignada al usuario.

Anulación y Comunicación de Baja

Cuando anulas un comprobante:
1

El correlativo NO se reutiliza

Si anulas la factura F001-00000050, ese número queda “quemado”. La siguiente factura será F001-00000051, no F001-00000050.
2

Se registra en ventas_anuladas

DB::table('ventas_anuladas')->insert([
  'id_venta' => $venta->id_venta,
  'serie' => $venta->serie,
  'numero' => $venta->numero,
  'motivo_anulacion' => $validated['motivo_anulacion'],
  'fecha_anulacion' => now(),
  'estado_comunicacion_baja' => '0',  // Pendiente de enviar a SUNAT
]);
3

Se envía Comunicación de Baja a SUNAT

  • La Comunicación de Baja es un documento especial que agrupa todas las anulaciones del día
  • Se envía usando el servicio comunicacionBaja() de SunatService
  • Tiene su propio correlativo, formato: RC-YYYYMMDD-001
  • Ejemplo: RC-20240315-001 (Primera comunicación de baja del 15/03/2024)
Referencia: app/Http/Controllers/VentasController.php, método anular(), líneas 410-483

Resumen Diario (Solo Boletas)

Las boletas requieren un proceso adicional:
1

Emitir la boleta

  • Se guarda en la base de datos
  • Se genera el XML
  • Estado inicial: estado_sunat = 0 (pendiente)
2

Generar Resumen Diario

  • Al final del día (o cuando decidas), agrupas todas las boletas del día
  • Generas un Resumen Diario (documento especial de SUNAT)
  • Formato del resumen: RC-YYYYMMDD-001
  • Ejemplo: RC-20240315-001 (Primer resumen del 15/03/2024)
3

Enviar a SUNAT

  • El Resumen Diario se envía de forma asíncrona
  • SUNAT retorna un ticket (número de control)
  • Debes consultar el estado del ticket después
  • Una vez aceptado, las boletas quedan validadas
Referencia: app/Services/SunatService.php, método resumenDiario(), líneas 1125-1227
Buena práctica: Genera el Resumen Diario automáticamente cada noche usando un cron job o tarea programada.

Nomenclatura de Archivos XML

Cuando el sistema genera archivos XML para SUNAT, sigue esta nomenclatura: Formato: {RUC}-{CODIGO_SUNAT}-{SERIE}-{NUMERO}.xml Ejemplos:
  • Factura: 20612706702-01-F001-00000123.xml
  • Boleta: 20612706702-03-B001-00000456.xml
  • Guía: 20612706702-09-T001-00000789.xml
  • Nota de Crédito: 20612706702-07-FC01-00000012.xml
CDR (respuesta de SUNAT):
  • Formato: R-{RUC}-{CODIGO_SUNAT}-{SERIE}-{NUMERO}.zip
  • Ejemplo: R-20612706702-01-F001-00000123.zip
Referencia: app/Services/SunatService.php, líneas 259-261

Validaciones del Sistema

Validación en VentasController

'serie' => 'required|string|max:4',
'numero' => 'required|integer',

Validación en Cliente según Tipo de Documento

// Factura (id_tido=2) requiere RUC (11 dígitos)
if ($validated['id_tido'] == 2 && strlen($documento) !== 11) {
    return response()->json([
        'success' => false,
        'message' => 'Para FACTURA se requiere RUC (11 dígitos).',
    ], 422);
}

// Boleta (id_tido=1) no permite RUC
if ($validated['id_tido'] == 1 && strlen($documento) === 11) {
    return response()->json([
        'success' => false,
        'message' => 'Para BOLETA use DNI u CE. Para RUC emita una Factura.',
    ], 422);
}
Referencia: app/Http/Controllers/VentasController.php, líneas 129-148

Errores Comunes y Soluciones

Causa: Intentas enviar un comprobante con un número que ya fue enviado a SUNAT anteriormente.Solución:
  1. No reenvíes el mismo comprobante
  2. Si cometiste un error, anula el comprobante erróneo
  3. Crea un nuevo comprobante con el siguiente correlativo
  4. Verifica que documentos_empresas tenga el numero correcto
Causa: Intentas usar una serie que no existe en documentos_empresas.Solución:
INSERT INTO documentos_empresas (id_empresa, id_tido, serie, numero)
VALUES (1, 2, 'F001', 0);
Reemplaza id_tido y serie según tu necesidad.
Causa: Puede haber un desajuste entre documentos_empresas y la tabla ventas.Solución:
  1. Consulta el último número en ventas:
    SELECT MAX(numero) FROM ventas WHERE serie = 'F001';
    
  2. Actualiza documentos_empresas:
    UPDATE documentos_empresas 
    SET numero = (SELECT MAX(numero) FROM ventas WHERE serie = 'F001')
    WHERE serie = 'F001';
    
Causa: La serie no cumple con el formato SUNAT o no está habilitada.Solución:
  1. Verifica que la serie tenga el formato correcto:
    • Facturas: F + 3 dígitos
    • Boletas: B + 3 dígitos
    • Guías: T + 3 dígitos
  2. Confirma que la serie esté habilitada en SUNAT SOL:
    • Ingresa a SUNAT SOL
    • Ve a Comprobantes Electrónicos → Gestionar series
    • Habilita la serie que necesitas

Buenas Prácticas

  • Facilita la identificación de qué sucursal o caja emitió el comprobante
  • Permite auditorías por punto de venta
  • Evita conflictos en sistemas multi-usuario
  • SUNAT puede rechazar comprobantes si detecta saltos en la numeración
  • El sistema de Santo Domingo evita esto automáticamente
  • Si necesitas anular, hazlo correctamente con Comunicación de Baja
  • Es la tabla crítica para la numeración
  • Si se pierde, puedes tener conflictos de correlativos
  • Haz respaldos regulares
  • A menos que migres de otro sistema, empieza en numero = 0
  • El sistema generará automáticamente 00000001 como primer comprobante
  • Más fácil de auditar
Mantén un registro de qué serie usa cada:
  • Sucursal
  • Caja
  • Usuario
  • Turno
Esto facilita la gestión y el soporte.

Consultas SQL Útiles

Ver todas las series configuradas

SELECT 
  ds.nombre AS tipo_documento,
  de.serie,
  de.numero AS ultimo_correlativo,
  CONCAT(de.serie, '-', LPAD(de.numero + 1, 8, '0')) AS proximo_comprobante
FROM documentos_empresas de
INNER JOIN documentos_sunat ds ON de.id_tido = ds.id_tido
WHERE de.id_empresa = 1
ORDER BY de.id_tido, de.serie;

Ver últimas ventas por serie

SELECT 
  serie,
  MAX(numero) AS ultimo_numero,
  COUNT(*) AS total_comprobantes
FROM ventas
WHERE id_empresa = 1
  AND estado = '1'  -- Activas
GROUP BY serie
ORDER BY serie;

Detectar huecos en la numeración

SELECT 
  v1.serie,
  v1.numero + 1 AS numero_faltante
FROM ventas v1
LEFT JOIN ventas v2 
  ON v1.serie = v2.serie 
  AND v1.numero + 1 = v2.numero
WHERE v1.id_empresa = 1
  AND v2.id_venta IS NULL
  AND v1.numero < (SELECT MAX(numero) FROM ventas v3 WHERE v3.serie = v1.serie)
ORDER BY v1.serie, numero_faltante;

Sincronizar documentos_empresas con ventas

UPDATE documentos_empresas de
INNER JOIN (
  SELECT serie, MAX(numero) AS max_numero
  FROM ventas
  WHERE id_empresa = 1
  GROUP BY serie
) v ON de.serie = v.serie
SET de.numero = v.max_numero
WHERE de.id_empresa = 1;

Próximos Pasos

Primera Venta

Crea tu primer comprobante usando las series configuradas

Configurar Empresa

Completa los datos de tu empresa antes de emitir

Notas de Crédito

Aprende a anular o corregir comprobantes con notas

API de Ventas

Documentación técnica de endpoints de ventas

Resumen

  • Serie: Código de 4 caracteres que identifica tipo de comprobante y punto de emisión
  • Correlativo: Número secuencial que se incrementa automáticamente
  • Formato completo: SERIE-CORRELATIVO (ej: F001-00000123)
  • Gestión: Tabla documentos_empresas almacena último correlativo usado
  • Validación: Sistema previene duplicados y saltos automáticamente
  • SUNAT: Cada tipo de comprobante requiere serie específica (F, B, T, etc.)
  • No reutilizar: Correlativos anulados no se pueden usar nuevamente
¡Series configuradas! Ya puedes emitir comprobantes electrónicos con numeración secuencial automática.

Build docs developers (and LLMs) love