Crear Complemento de Pago
Este endpoint permite crear y sellar un CFDI de Recepción de Pagos (Complemento de Pago).
- Método HTTP:
POST - URL:
/invoices
Cabeceras
"application/json"*Debes usar uno de los dos métodos de autenticación: Authorization (Bearer JWT) o x-api-key.
Este endpoint tiene un límite de 30 solicitudes por minuto por organización.
Estructura del Request
El cuerpo de la petición es un objeto JSON que representa el CrearComprobanteDto.
Objeto Principal: CrearComprobanteDto
"P""XXX"Objeto: ReceptorDto
Objeto: ConceptoDto
"Pago"01"84111506""ACT""01"Objeto Principal: ComplementoPagoDto
Objeto: PagoDto
Objeto: DocumentoRelacionadoDto
Objeto: PagoImpuestosDto
Objeto: PagoTrasladoDto
Objeto: PagoRetencionDto
Ejemplos de Código
- cURL
- Python
curl -X POST https://sandbox.lummy.io/invoices \
-H "Content-Type: application/json" \
-H "x-organization-id: ${LUMMY_ORG_ID}" \
-H "x-api-key: ${LUMMY_API_KEY}" \
-H "x-idempotency: $(uuidgen)" \
-d '{
"tipoDeComprobante": "P",
"receptor": {
"rfc": "XAXX010101000",
"nombre": "Receptor de Prueba",
"regimenFiscal": "601",
"domicilioFiscal": "12345",
"email": "receptor@ejemplo.com"
},
"conceptos": [
{
"claveProdServ": "84111506",
"cantidad": 1,
"claveUnidad": "ACT",
"descripcion": "Pago",
"valorUnitario": 0,
"objetoImp": "01"
}
],
"moneda": "XXX",
"exportacion": "01",
"lugarExpedicion": "06500",
"fecha": "2025-01-15T12:00:00",
"complementoPago": {
"pagos": [
{
"fechaPago": "2025-01-15T12:00:00",
"formaDePagoP": "03",
"monedaP": "MXN",
"monto": 100,
"documentosRelacionados": [
{
"idDocumento": "f3a3b1e0-0b7a-4b1a-9b0a-0a0b0c0d0e0f",
"monedaDR": "MXN",
"numParcialidad": 1,
"impSaldoAnt": 100,
"impPagado": 100,
"objetoImpDR": "01"
}
],
"impuestosP": {}
}
]
}
}'
import os
import requests
import uuid
headers = {
'Content-Type': 'application/json',
'x-organization-id': os.environ.get('LUMMY_ORG_ID'),
'x-api-key': os.environ.get('LUMMY_API_KEY'),
'x-idempotency': str(uuid.uuid4()),
}
json_data = {
'tipoDeComprobante': 'P',
'receptor': {
'rfc': 'XAXX010101000',
'nombre': 'Receptor de Prueba',
'regimenFiscal': '601',
'domicilioFiscal': '12345',
'email': 'receptor@ejemplo.com',
},
'conceptos': [
{
'claveProdServ': '84111506',
'cantidad': 1,
'claveUnidad': 'ACT',
'descripcion': 'Pago',
'valorUnitario': 0,
'objetoImp': '01',
},
],
'moneda': 'XXX',
'exportacion': '01',
'lugarExpedicion': '06500',
'fecha': '2025-01-15T12:00:00',
'complementoPago': {
'pagos': [
{
'fechaPago': '2025-01-15T12:00:00',
'formaDePagoP': '03',
'monedaP': 'MXN',
'monto': 100,
'documentosRelacionados': [
{
'idDocumento': 'f3a3b1e0-0b7a-4b1a-9b0a-0a0b0c0d0e0f',
'monedaDR': 'MXN',
'numParcialidad': 1,
'impSaldoAnt': 100,
'impPagado': 100,
'objetoImpDR': '01',
},
],
'impuestosP': {},
},
],
},
}
response = requests.post('https://sandbox.lummy.io/invoices', headers=headers, json=json_data)
print(response.json())
Respuesta Exitosa (HTTP 201 Created)
Todas las respuestas siguen el formato estándar StandardResponse:
{
"requestId": "abc123-def456",
"data": {
"invoiceId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"cfdiUuid": "cfa52b8b-93f2-4e6b-8c73-64ad88deb17c",
"verificationUrl": "https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=cfa52b8b-93f2-4e6b-8c73-64ad88deb17c",
"xmlUrl": "https://lummy-invoices.s3.amazonaws.com/cfdi/cfa52b8b-93f2-4e6b-8c73-64ad88deb17c.xml",
"status": "stamped"
},
"timestamp": "2025-01-20T10:00:00.000Z",
"path": "/invoices",
"method": "POST"
}
| Campo | Tipo | Descripción |
|---|---|---|
requestId | string | ID único de la solicitud para trazabilidad |
data.invoiceId | string (UUID) | ID interno de la factura en Lummy |
data.cfdiUuid | string (UUID) | UUID fiscal del SAT - Folio fiscal del CFDI timbrado |
data.verificationUrl | string (URL) | URL para verificar el CFDI en el portal del SAT |
data.xmlUrl | string (URL) | URL pública para descargar el XML timbrado |
data.status | string | Estado del timbrado: stamped o pending_stamping |
timestamp | string (ISO) | Fecha y hora de la respuesta |
path | string | Ruta del endpoint |
method | string | Método HTTP de la solicitud |
El archivo PDF se genera de forma asíncrona después del timbrado y se envía automáticamente por correo electrónico al receptor.
Respuesta Pendiente de Timbrado (HTTP 201 Created)
Si el PAC no responde o hay un error temporal, la factura se guarda y se reintenta automáticamente:
{
"requestId": "abc123-def456",
"data": {
"invoiceId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
"cfdiUuid": "",
"verificationUrl": "",
"xmlUrl": "",
"status": "pending_stamping",
"retryInfo": {
"nextRetryAt": "2025-01-20T10:05:00.000Z",
"attempt": 1,
"maxAttempts": 5
}
},
"timestamp": "2025-01-20T10:00:00.000Z",
"path": "/invoices",
"method": "POST"
}
| Campo | Tipo | Descripción |
|---|---|---|
data.status | string | pending_stamping indica que el timbrado está en cola |
data.retryInfo.nextRetryAt | string (ISO) | Fecha y hora del próximo reintento automático |
data.retryInfo.attempt | number | Número de intento actual |
data.retryInfo.maxAttempts | number | Número máximo de reintentos (5) |
El sistema reintenta automáticamente el timbrado con backoff exponencial. Puedes consultar el estado con GET /invoices/{invoiceId}.
Respuestas de Error
Todas las respuestas de error siguen el formato estándar StandardResponse:
{
"requestId": "abc123-def456",
"error": {
"message": "Descripción del error",
"code": "ERROR_CODE",
"status": 400
},
"timestamp": "2025-01-20T10:00:00.000Z",
"path": "/invoices",
"method": "POST"
}
| Código | Descripción |
|---|---|
| 400 | Datos de entrada inválidos (UUID de documento relacionado, montos, etc.) |
| 401 | Token de autenticación inválido o expirado |
| 403 | Sin permisos (suscripción inactiva, scope insuficiente) |
| 404 | Sucursal o CSD no encontrado |
| 409 | Clave de idempotencia ya usada |
| 422 | Rechazo del PAC/SAT (UUID de factura relacionada no existe, saldos incorrectos) |
| 429 | Rate limit excedido (máximo 30 solicitudes por minuto) |
| 500 | Error interno del servidor |
Errores Comunes del Complemento de Pago
| Error SAT | Descripción |
|---|---|
CFDI33184 | El UUID del documento relacionado no existe en el SAT |
CFDI33185 | El monto pagado excede el saldo pendiente del documento |
CFDI33186 | La suma de pagos no coincide con el monto total |
CFDI33187 | El documento relacionado ya está completamente pagado |