Procedimiento de Revisión Quincenal de Comprobantes Electrónicos
Periodo evaluado: últimos 15 días (prior 15 days)
1. Objetivo
Establecer un procedimiento detallado y sistemático para la revisión quincenal de comprobantes electrónicos emitidos desde el sistema POS, con el fin de identificar incongruencias entre:
- Sistema POS (base de datos interna)
- Sistema PSE
- Estado real del comprobante ante SUNAT
La revisión permite detectar errores operativos, inconsistencias de estado, problemas de emisión, cancelación y facturación, y dejar trazabilidad clara para su posterior corrección.
2. Alcance
Este procedimiento aplica a:
- Todos los comprobantes que hayan sido intentados emitir desde el sistema POS
- Periodo de análisis: últimos 15 días calendario
- Incluye comprobantes:
- Emitidos correctamente
- No enviados
- Rechazados
- Cancelados o pendientes de cancelación
- Duplicados
- Con errores de correlativo
- Con inconsistencias entre sistemas
⚠️ Este procedimiento es de revisión y validación.
Las correcciones pueden requerir acciones manuales y/o aprobación del cliente.
3. Responsabilidad
- La revisión es ejecutada por el responsable técnico asignado.
- Las correcciones que impactan información fiscal o montos requieren validación y, en algunos casos, aprobación del cliente.
- Todo hallazgo debe quedar documentado.
4. Fuentes de Información
- Base de datos del sistema POS
- Sistema PSE
- SUNAT (a través del PSE)
- Script de validación (
go-utils) - Exportes CSV generados para revisión manual
5. Procedimiento General de Revisión
La revisión se realiza siguiendo los pasos descritos a continuación, en el orden indicado.
6. Revisión de Comprobantes No Enviados al PSE (Waiting)
Descripción
Corresponde a comprobantes que no llegaron a enviarse al PSE, generalmente por:
- Errores del sistema
- Errores del PSE
- Errores de SUNAT
- Fallos durante el proceso de emisión
Obtención de la información
- Se obtiene mediante una query específica sobre la base de datos del POS.
Query de referencia:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET @DATE_CHECK := '2026-01-01 05:00:00';
-- PENDING BILLS
select o.name,
s.name,
eb.order_uuid,
eb.uuid,
eb.type,
eb.series,
eb.number,
eb.date_of_issue,
eb.link as LINK,
eb.latest_status AS ESTADO,
eb.retry_count,
SUBSTRING_INDEX(eb.errors, '\n', -2),
payload,
eb.organization_uuid,
eb.created_at,
eb.updated_at
from electronic_bills eb
left join stores s on eb.venue_uuid = s.uuid
left join organizations o on eb.organization_uuid = o.uuid
where eb.created_at >= @DATE_CHECK
AND (eb.latest_status = 'waiting' || eb.latest_status = 'pending' )
AND eb.deleted_at IS NULL
AND s.uses_system = 1
order by eb.updated_at;
-- INVALID
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET @DATE_CHECK := '2026-01-01 05:00:00';
-- NON VALID VOUCHERS
CREATE TEMPORARY TABLE IF NOT EXISTS NonValidVouchers AS (select eb.uuid,
eb.type,
eb.series,
eb.number,
eb.link,
eb.date_of_issue,
eb.latest_status,
eb.order_uuid,
eb.retry_count,
eb.errors,
eb.payload,
eb.created_at,
eb.updated_at,
eb.deleted_at,
eb.venue_uuid
from electronic_bills eb
where (link = 'https://idbiperu.pse.pe' or link = '')
and eb.created_at >= @DATE_CHECK and eb.deleted_at is null);
-- NON VALID VOUCHERS
SELECT o.name as organization, s.name as store, JSON_EXTRACT(eb.payload, "$.total") as total, eb.*
FROM NonValidVouchers eb
LEFT JOIN stores s ON eb.venue_uuid = s.uuid AND s.uses_system = 1
LEFT JOIN organizations o ON s.owner_uuid = o.uuid
WHERE s.uuid IS NOT NULL
ORDER BY eb.updated_at;
DROP TEMPORARY TABLE NonValidVouchers;
Acción
- Revisar cada comprobante manualmente.
- Determinar si:
- Basta con un reintento de envío.
- Se requiere modificar el payload (errores de cálculo, montos, impuestos).
- Registrar el resultado del análisis.
7. Revisión de Comprobantes Pendientes de Cancelación
Descripción
Comprobantes que deberían estar cancelados pero no cuentan con ticket de cancelación registrado en el sistema.
Obtención de la información
- Se obtiene mediante una query filtrando comprobantes sin ticket de cancelación.
Query de referencia:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET @DATE_CHECK := '2025-10-01 05:00:00';
-- PENDING CANCELED BILLS
select o.name,
s.name,
eb.uuid,
eb.series,
eb.number,
eb.link as LINK,
eb.latest_status AS ESTADO,
eb.cancel_ticket AS TICKET,
eb.created_at,
eb.updated_at
from electronic_bills eb FORCE INDEX (idx_electronic_bills_created_status_cancel_deleted)
left join stores s on eb.venue_uuid = s.uuid
left join organizations o on eb.organization_uuid = o.uuid and o.enabled = 1
where eb.created_at BETWEEN @DATE_CHECK AND DATE_ADD(DATE_SUB(CURDATE(), INTERVAL 1 DAY), INTERVAL 5 HOUR)
AND eb.latest_status = 'canceled'
AND eb.cancel_ticket IS NULL
AND eb.deleted_at IS NULL
AND s.uses_system = 1
and o.name IS NOT NULL
order by eb.updated_at;
Casos posibles
- El comprobante fue emitido pero la cancelación no se completó.
- El comprobante no fue enviado aún, por lo que:
- Debe emitirse primero.
- Luego proceder con la cancelación.
Acción
- Identificar el caso.
- Ejecutar la secuencia correcta de emisión y cancelación.
- Registrar el resultado.
8. Revisión de Saltos de Correlativo
Descripción
Casos donde se detectan saltos o discontinuidades en el correlativo de comprobantes.
Obtención de la información
- Identificados mediante una query específica.
Query de referencia:
-ET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET @DATE_CHECK := '2026-01-01 05:00:00';
-- MISSING
WITH NumberedDocuments AS (SELECT created_at as Fecha,
venue_uuid as Venue,
organization_uuid as Organization,
type as TipoDocumento,
series as GroupPrefix,
number as DocumentNumberPart,
LAG(number)
OVER (PARTITION BY organization_uuid, type, series ORDER BY number) as PreviousDocumentNumberPart
FROM electronic_bills
WHERE created_at > @DATE_CHECK and deleted_at is null),
MissingDocuments AS (SELECT Fecha,
Venue,
Organization,
TipoDocumento,
GroupPrefix,
PreviousDocumentNumberPart + 1 as MissingFrom,
DocumentNumberPart - 1 as MissingTo
FROM NumberedDocuments
WHERE PreviousDocumentNumberPart IS NOT NULL
AND DocumentNumberPart - PreviousDocumentNumberPart > 1)
SELECT o.uuid,
o.name as Name,
v.uuid AS VID,
v.name as Venue,
Fecha,
TipoDocumento,
GroupPrefix,
MissingFrom,
MissingTo,
MissingTo - MissingFrom + 1 as MissingCount
FROM MissingDocuments
LEFT JOIN venues v ON MissingDocuments.Venue = v.uuid
LEFT JOIN organizations o ON MissingDocuments.Organization = o.uuid
ORDER BY GroupPrefix, MissingFrom, MissingTo;
Acción
- Analizar el motivo del salto:
- Error de emisión
- Error de reintento
- Error de numeración
- Resolver el caso según corresponda.
- Documentar la decisión tomada.
9. Revisión de Comprobantes Duplicados
Descripción
Casos donde existen dos o más comprobantes asociados indebidamente, ya sea por reintentos o errores del sistema.
Obtención de la información
- Detectados mediante una query de duplicados.
Query de referencia:
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET @DATE_CHECK := '2026-01-01 05:00:00';
create temporary table temp_electronic_bills as
select *
from electronic_bills
where created_at >= @DATE_CHECK
and deleted_at is null;
alter table temp_electronic_bills
add index idx_venue_uuid_series_number (venue_uuid, serial_number, number);
-- DUPLICATED RECORDS
WITH cte AS (SELECT *
, COUNT(*) OVER (PARTITION BY venue_uuid,type, serial_number, number) AS num_of_duplicates_group
, ROW_NUMBER() OVER (PARTITION BY venue_uuid, type, serial_number, number ORDER BY number) AS pos_in_group
FROM temp_electronic_bills)
SELECT v.uuid,
v.name,
date_of_issue,
qr_code,
o.total,
cte.uuid,
cte.latest_status,
cte.latest_status_id,
type,
serial_number,
number,
CONCAT('OV-', o.correlative),
o.uuid,
num_of_duplicates_group,
pos_in_group
FROM cte
left join venues v on cte.venue_uuid = v.uuid
left join orders o on cte.order_uuid = o.uuid
WHERE num_of_duplicates_group > 1
and number is not null
and cte.deleted_at is null;
DROP TEMPORARY TABLE temp_electronic_bills;
Acción
- Revisar cada caso individualmente.
- Determinar cuál comprobante es válido.
- Evaluar necesidad de cancelación o regularización.
- En caso de impacto fiscal, coordinar aprobación del cliente.
10. Revisión de Inconsistencias POS vs PSE
Descripción
Comparación entre:
- Lo registrado en la base de datos del POS
- La información real del comprobante en el sistema PSE
Herramienta
- Script en Go:
go-utils - El script:
- Consulta comprobante por comprobante
- Verifica estado y datos
- Exporta resultados a un archivo CSV
Comparación de montos
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET @DATE_CHECK := '2026-01-01 05:00:00';
SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));
-- Q_COMPARE_OPTIMAL
WITH SELECTED AS (SELECT o.uuid as order_id,
o.correlative,
o.payable_amount + o.delivery_amount AS order_total,
s.name as store_name,
s.uuid as store_id
FROM orders o
LEFT JOIN stores s ON o.store_uuid = s.uuid
WHERE o.created_at >= @DATE_CHECK
AND o.deleted_at IS NULL),
TOTAL_BILLED AS (SELECT *
FROM electronic_bills eb
JOIN SELECTED s ON eb.order_uuid = s.order_id
WHERE eb.latest_status IN ('sent', 'sent_inoperative')
AND eb.deleted_at IS NULL),
AMOUNTS AS (SELECT order_id,
CONCAT('OV-', correlative) as correlative,
store_id,
store_name,
order_total,
IF(type = 1 or type = 2, JSON_EXTRACT(payload, '$.total'), 0) AS POSITIVE,
IF(type = 3, JSON_EXTRACT(payload, '$.total'), 0) AS NEGATIVE,
JSON_EXTRACT(payload, '$.')
FROM TOTAL_BILLED),
FINAL AS (SELECT order_id,
correlative,
store_id,
store_name,
order_total,
SUM(POSITIVE) AS POSITIVE,
SUM(NEGATIVE) AS NEGATIVE,
SUM(POSITIVE - NEGATIVE) AS TOTAL,
IFNULL(SUM(a.amount), 0) AS ANTICIPO
FROM AMOUNTS f
LEFT JOIN advance_order ao ON ao.order_uuid = f.order_id
LEFT JOIN advances a ON a.uuid = ao.advance_uuid
GROUP BY order_id)
SELECT order_id,
correlative,
store_id,
store_name,
order_total,
POSITIVE,
NEGATIVE,
TOTAL,
ANTICIPO,
ABS(order_total - ANTICIPO - TOTAL) AS DIFF
FROM FINAL f
LEFT JOIN advance_order ao ON ao.order_uuid = f.order_id
LEFT JOIN advances a ON a.uuid = ao.advance_uuid
WHERE order_total - TOTAL != 0
GROUP BY order_id
Ejecución
- Ejecutar el script para el periodo de los últimos 15 días.
- Generar el archivo CSV para revisión manual.
11. Validaciones Manuales sobre el CSV
Durante la revisión del CSV se debe validar:
- Que no existan estados inconsistentes.
- Que un comprobante no tenga más de una factura asociada.
- Que el monto de la orden coincida con el total facturado.
- Que no existan comprobantes marcados como aceptados en el sistema pero rechazados en SUNAT.
Cada inconsistencia debe:
- Analizarse caso por caso.
- Documentarse.
- Evaluar si requiere corrección técnica o aprobación del cliente.
12. Aprobaciones del Cliente
Algunas correcciones requieren aprobación explícita del cliente, especialmente cuando:
- Se modifican montos.
- Se corrigen comprobantes ya enviados.
- Se realizan cancelaciones posteriores.
La aprobación debe quedar documentada y referenciada en el registro de la revisión.
13. Registro de la Revisión
Al finalizar la revisión quincenal se debe dejar constancia de:
- Periodo revisado
- Fecha de ejecución
- Cantidad total de comprobantes revisados
- Cantidad de casos detectados por tipo:
- No enviados
- Pendientes de cancelación
- Saltos de correlativo
- Duplicados
- Inconsistencias POS vs PSE
- Casos corregidos
- Casos pendientes
- Casos que requieren aprobación del cliente
14. Consideraciones Finales
- Este procedimiento debe ejecutarse cada 15 días sin excepción.
- La revisión no debe omitirse aunque no existan alertas previas.
- Toda acción debe ser trazable y documentada.
- En caso de duda o impacto fiscal relevante, escalar antes de corregir.
Responsable del procedimiento:
Equipo técnico / Infraestructura
Última actualización: 16/01/2026