Tipos de Envío
SUNAT maneja dos modalidades de envío según el tipo de comprobante:Envío Síncrono (SOAP)
Respuesta inmediata con CDR. Documentos:- Facturas (01)
- Notas de Crédito (07)
- Notas de Débito (08)
Envío Asíncrono (Tickets)
Requiere polling posterior. Documentos:- Boletas (03) - Vía Resumen Diario
- Guías de Remisión (09, 31) - Vía API REST GRE
- Comunicación de Baja (anulación de facturas)
Tiempo de procesamiento de tickets:
- Resumen Diario de Boletas: 5-30 minutos
- Guías de Remisión: 2-10 segundos
- Comunicación de Baja: 5-15 minutos
98 indica “en proceso”.Envío de Facturas (Síncrono)
Generar XML firmado
Al crear una venta (factura), el sistema puede generar el XML automáticamente o hacerlo bajo demanda.Endpoint:Proceso interno (
SunatService::generarXml() línea 159-247):-
Carga la venta con relaciones:
-
Construye objetos Greenter (
Invoice,Company,Client,SaleDetail) -
Calcula montos con IGV:
-
Añade leyenda en letras:
-
Firma el XML con el certificado:
-
Guarda en
storage/app/sunat/xml/{ruc}/{nombre_archivo}.xml -
Extrae el hash del XML firmado:
-
Actualiza la venta:
Enviar a SUNAT
Una vez generado el XML, envíealo:Endpoint:Proceso interno (
SunatService::enviarComprobante() línea 249-317):-
Lee el XML desde storage:
-
Envía vía SOAP:
-
Si es exitoso:
- Extrae el CDR (Constancia de Recepción)
- Guarda el CDR en
storage/app/sunat/cdr/{ruc}/R-{nombreArchivo}.zip - Actualiza la venta:
-
Si es rechazado:
- Registra el error en logs:
- Actualiza la venta:
- Registra el error en logs:
Envío de Notas de Crédito/Débito
El flujo es similar al de facturas:-
El XML incluye referencia al documento afectado:
-
Al aceptarse, la venta original se marca como anulada:
Envío de Guías de Remisión (Asíncrono)
Las guías usan la API REST GRE de SUNAT con autenticación OAuth.Generar XML de guía
SunatService::generarGuiaRemisionXml() (línea 567-666):- Construye objeto
Despatchcon envio (Shipment) - Incluye conductor, vehículo, direcciones de partida/llegada
- Tipo doc: ‘09’ (remitente) o ‘31’ (transportista)
Enviar a API GRE
SunatService::enviarGuiaRemision() (línea 766-842):-
Obtener token OAuth:
-
Crear ZIP del XML:
-
Enviar vía REST:
-
Guardar ticket:
Estados de Envío (estado_sunat)
| Código | Significado | Descripción |
|---|---|---|
null | Sin enviar | Aún no se ha intentado el envío |
0 | Generado | XML generado pero no enviado |
1 | Aceptado | SUNAT aceptó el comprobante |
2 | Anulado | Comprobante anulado (por nota de crédito o comunicación de baja) |
3 | Rechazado/En proceso | Rechazado por SUNAT o esperando ticket |
Estructura del CDR
El CDR es un ZIP que contiene un XML de respuesta:0: Aceptado0001: Aceptado con observaciones (ej: RUC del cliente no existe)- Otros: Ver Solucionar Errores SUNAT
Reintentos Automáticos
El sistema registra intentos fallidos en el campointentos:
Envío Masivo
Para enviar múltiples comprobantes:Solución de Problemas
Error: 'XML no encontrado. Genere el XML primero'
Error: 'XML no encontrado. Genere el XML primero'
El campo
xml_url de la venta está vacío. Debe generar el XML antes de enviar:Error SUNAT: 'El certificado no es válido' (2335)
Error SUNAT: 'El certificado no es válido' (2335)
Problema con el certificado digital:
- Verifique que el .pem exista en
storage/app/sunat/certificados/{ruc}-cert.pem - Verifique que no haya expirado:
openssl x509 -in cert.pem -noout -dates - Verifique que coincida con el RUC
Error: 'SOAP-ERROR: Parsing WSDL'
Error: 'SOAP-ERROR: Parsing WSDL'
Problema de conectividad con SUNAT:
- Verifique conexión a internet del servidor
- Verifique que el endpoint sea correcto en
config/sunat.php - Pruebe acceso manual:
curl https://e-factura.sunat.gob.pe
¿Cómo reenvío un comprobante rechazado?
¿Cómo reenvío un comprobante rechazado?
Si el rechazo fue por un error corregible:
- Corrija el error en la venta (ej: datos del cliente)
- Regenere el XML:
POST /api/ventas/{id}/generar-xml - Reenvíe:
POST /api/ventas/{id}/enviar-sunat
Logs de Envío
Los errores se registran enstorage/logs/laravel.log:
.env: