Validar Factura
Valida un XML de CFDI contra las reglas del SAT y del PAC sin timbrarlo. Util para verificar que tu factura es correcta antes de enviarla a timbrar.
Uso recomendado
Utiliza este endpoint para validar tus XMLs antes de timbrar, especialmente cuando estas desarrollando tu integracion o cuando tienes XMLs generados por sistemas externos.
Endpoint
POST https://api.lummy.io/v1/invoices/validate
| Entorno | URL |
|---|---|
| Producción | https://api.lummy.io/v1/invoices/validate |
| Sandbox | https://sandbox.lummy.io/v1/invoices/validate |
Headers
{
"Content-Type": stringrequerido
↳Tipo de contenido del cuerpo de la petición. Debe ser "application/json" para indicar que se está enviando un objeto JSON con el XML a validar.
}
Body Parameters
{
"xml": stringrequerido
↳Contenido completo del XML del CFDI a validar. Puede ser un XML sellado (con el atributo Sello) o sin sellar. El servicio validará la estructura XML según el esquema XSD del SAT, los catálogos fiscales, las reglas de negocio del anexo 20, y opcionalmente la integridad del sello digital si está presente.
}
Ejemplos de Codigo
- cURL
- Node.js (TypeScript)
- Python
- PHP (Guzzle)
curl -X POST https://sandbox.lummy.io/invoices/validate \
-H "Content-Type: application/json" \
-d '{
"xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><cfdi:Comprobante xmlns:cfdi=\"http://www.sat.gob.mx/cfd/4\" ..."
}'
import axios from 'axios';
import fs from 'fs';
interface ValidationResult {
isValid: boolean;
message: string;
detail?: string;
}
async function validarFactura(xmlContent: string): Promise<ValidationResult> {
const API_URL = 'https://sandbox.lummy.io/invoices/validate';
try {
const response = await axios.post<ValidationResult>(API_URL, {
xml: xmlContent,
}, {
headers: {
'Content-Type': 'application/json',
},
});
console.log('Validacion exitosa:', response.data);
return response.data;
} catch (error) {
if (axios.isAxiosError(error) && error.response?.status === 400) {
console.error('Errores de validacion:', error.response.data);
throw error;
}
throw error;
}
}
// Ejemplo: validar desde archivo
const xml = fs.readFileSync('./factura.xml', 'utf-8');
validarFactura(xml);
import requests
def validar_factura(xml_content: str):
api_url = "https://sandbox.lummy.io/invoices/validate"
headers = {
"Content-Type": "application/json",
}
payload = {
"xml": xml_content,
}
try:
response = requests.post(api_url, json=payload, headers=headers)
response.raise_for_status()
data = response.json()
print(f"Validacion exitosa: {data['message']}")
return data
except requests.exceptions.HTTPError as e:
if e.response.status_code == 400:
error_data = e.response.json()
print(f"Errores de validacion: {error_data}")
raise
if __name__ == "__main__":
with open("./factura.xml", "r") as f:
xml = f.read()
validar_factura(xml)
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
function validarFactura(string $xmlContent): array
{
$client = new Client([
'base_uri' => 'https://sandbox.lummy.io',
'headers' => [
'Content-Type' => 'application/json',
],
]);
try {
$response = $client->post('/invoices/validate', [
'json' => ['xml' => $xmlContent],
]);
$data = json_decode($response->getBody(), true);
echo "Validacion exitosa: " . $data['message'] . "\n";
return $data;
} catch (ClientException $e) {
if ($e->getResponse()->getStatusCode() === 400) {
$errorData = json_decode($e->getResponse()->getBody(), true);
echo "Errores de validacion: " . print_r($errorData, true) . "\n";
}
throw $e;
}
}
// Ejemplo: validar desde archivo
$xml = file_get_contents('./factura.xml');
validarFactura($xml);
Respuestas
200 OK
El XML es valido segun las reglas del SAT y del PAC.
{
"isValid": true,
"message": "XML valido",
"detail": "Validacion de Estructura Correcta"
}
400 Bad Request
El XML contiene errores de validacion.
{
"statusCode": 400,
"message": "Errores de validacion",
"error": "Bad Request",
"details": [
"CFDI40139 - El campo Nombre del emisor no corresponde con el registrado en el SAT",
"305 - La fecha de emision no esta dentro de la vigencia del CSD"
]
}
Codigos de Error Comunes
| Codigo | Descripcion |
|---|---|
CFDI40139 | Nombre del emisor no corresponde con el registrado en el SAT |
CFDI40137 | RFC del receptor no valido o no registrado |
CFDI33101 | UUID relacionado no encontrado |
305 | Fecha de emision fuera de la vigencia del CSD |
301 | Certificado revocado o no vigente |
302 | Sello digital invalido |
Diferencia con timbrado
Este endpoint solo valida el XML, no lo timbra. Para generar el CFDI fiscal completo con UUID, utiliza los endpoints:
- Crear Factura - Proceso completo automatico
- Sellar Factura - Solo timbrado de XML ya sellado
Validaciones Realizadas
El PAC realiza las siguientes validaciones:
- Estructura XML - Cumplimiento del esquema XSD del SAT
- Datos del Emisor - RFC, nombre y regimen fiscal
- Datos del Receptor - RFC, uso del CFDI y regimen fiscal
- Certificado - Vigencia y validez del CSD
- Sello Digital - Integridad de la cadena original
- Catalogos SAT - Claves validas de productos, unidades, etc.
- Reglas de Negocio - Compatibilidad de campos segun tipo de comprobante