Ir al contenido

Validación SUNAT

openUBL valida automáticamente cada documento generado contra los esquemas XSD de SUNAT y las reglas de negocio definidas en las Resoluciones de Superintendencia. Esto garantiza que el XML sea rechazado antes de llegar a SUNAT si contiene errores estructurales.

Por defecto, todos los endpoints de creación ejecutan validación antes de devolver el XML:

Ventana de terminal
POST /api/v1/invoice/create # validate=true por defecto
POST /api/v1/credit-note/create # validate=true por defecto
POST /api/v1/debit-note/create # validate=true por defecto
POST /api/v1/summary-documents/create # validate=true por defecto
POST /api/v1/voided-documents/create # validate=true por defecto
POST /api/v1/perception/create # validate=true por defecto
POST /api/v1/retention/create # validate=true por defecto

Si la validación falla, el endpoint responde con código 400 y una lista de errores:

{
"detail": [
"XSD validation error: Element 'cbc:ID': [facet 'pattern'] ...",
"Business rule: RUC must be 11 digits"
]
}

Para omitir la validación —por ejemplo, durante desarrollo o pruebas— usa el parámetro de consulta validate:

import requests
response = requests.post(
"http://localhost:8000/api/v1/invoice/create?validate=false",
json={...},
)
xml = response.json()["xml"]

Comprueba que el XML cumple la estructura UBL 2.1 definida por OASIS y SUNAT:

  • Elementos obligatorios presentes
  • Tipos de datos correctos
  • Secuencia de elementos válida
  • Atributos requeridos completos

Verifica restricciones específicas de SUNAT:

ReglaDescripción
RUC11 dígitos numéricos
Serie facturaInicia con F seguido de 2-3 caracteres alfanuméricos
Serie boletaInicia con B seguido de 2-3 caracteres alfanuméricos
FechasFormato YYYY-MM-DD válido
MontosValores positivos con 2 decimales
FirmaEstructura de firma digital presente (validación posterior a /sign)

Después de firmar un documento con /api/v1/sign, puedes validar la estructura de la firma:

from openubl.validator import SunatValidator
validator = SunatValidator()
errors = validator.validate_signed_xml(signed_xml)
if errors:
print("Errores de firma:", errors)
else:
print("Firma válida")