Saltar al contenido principal

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

{
"Content-Type": string,requerido
Formato del cuerpo de la petición.
Valores permitidos: "application/json"
"Authorization": string,opcional
Token de autenticación Bearer JWT en formato: Bearer <token>
"x-organization-id": string,requerido
Identificador único de la organización emisora del CFDI.
Formato: uuid
"x-api-key": string,opcional
API Key como método alternativo de autenticación en lugar del token Bearer.
"x-idempotency": stringrequerido
UUID único para prevenir la creación de comprobantes duplicados. Si se envía el mismo UUID en solicitudes posteriores, se devolverá el comprobante original.
Formato: uuid
}

*Debes usar uno de los dos métodos de autenticación: Authorization (Bearer JWT) o x-api-key.

Rate Limiting

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

{
"tipoDeComprobante": string,requerido
Tipo de comprobante. Debe ser P para CFDI de Recepción de Pagos (Complemento de Pago).
Valores permitidos: "P"
"receptor": object,requerido
Objeto que contiene los datos fiscales del receptor del CFDI (cliente que realiza el pago).
"conceptos": array,requerido
Arreglo de conceptos del CFDI. Para complementos de pago debe contener un único concepto con valores predeterminados.
"moneda": string,requerido
Moneda del CFDI. Para complementos de pago debe ser XXX (sin moneda), ya que el pago puede relacionar documentos en distintas monedas.
Valores permitidos: "XXX"
"exportacion": string,requerido
Clave que indica si el comprobante ampara una operación de exportación definitiva, temporal o no aplica.
"lugarExpedicion": string,requerido
Código postal del domicilio fiscal del emisor del comprobante (sucursal o matriz).
Patrón: ^[0-9]{5}$
"fecha": string,requerido
Fecha y hora de expedición del comprobante en formato ISO 8601 (YYYY-MM-DDTHH:mm:ss).
Formato: date-time
"complementoPago": objectrequerido
Nodo que contiene la información del Complemento de Recepción de Pagos versión 2.0. Este nodo es obligatorio para comprobantes tipo P.
}

Objeto: ReceptorDto

{
"rfc": string,requerido
RFC del receptor del CFDI (cliente que realiza el pago). Debe tener 12 caracteres para personas morales o 13 para personas físicas.
Longitud: 12-13 caracteres · Patrón: ^[A-ZÑ&]{3,4}[0-9]{6}[A-Z0-9]{3}$
"nombre": string,requerido
Nombre o Razón Social del receptor. Debe coincidir con el nombre registrado en el SAT para el RFC proporcionado.
Longitud máxima: 254 caracteres
"regimenFiscal": string,requerido
Clave del régimen fiscal del receptor según el catálogo c_RegimenFiscal del SAT (ejemplo: 601 - General de Ley Personas Morales, 612 - Personas Físicas con Actividades Empresariales).
"domicilioFiscal": string,requerido
Código postal del domicilio fiscal del receptor registrado ante el SAT.
Patrón: ^[0-9]{5}$
"email": string,requerido
Correo electrónico del receptor para el envío automático del CFDI timbrado en formato XML y PDF.
Formato: email
"telefono": stringopcional
Número telefónico de contacto del receptor (opcional).
}

Objeto: ConceptoDto

{
"descripcion": string,requerido
Descripción del concepto. Para complementos de pago debe ser exactamente "Pago".
Valores permitidos: "Pago"
"valorUnitario": number,requerido
Precio unitario del concepto. Para complementos de pago debe ser 0.
Valores permitidos: 0
"cantidad": number,requerido
Cantidad de unidades del concepto. Para complementos de pago debe ser 1.
Valores permitidos: 1
"claveProdServ": string,requerido
Clave del producto o servicio según el catálogo c_ClaveProdServ del SAT. Para complementos de pago debe ser 84111506 (Servicios de facturación).
Valores permitidos: "84111506"
"claveUnidad": string,requerido
Clave de la unidad de medida según el catálogo c_ClaveUnidad del SAT. Para complementos de pago debe ser ACT (Actividad).
Valores permitidos: "ACT"
"objetoImp": stringrequerido
Clave que indica si el concepto es objeto de impuesto según el catálogo c_ObjetoImp. Para complementos de pago debe ser 01 (No objeto de impuesto).
Valores permitidos: "01"
}

Objeto Principal: ComplementoPagoDto

{
"pagos": arrayrequerido
Arreglo que contiene uno o más pagos recibidos. Cada pago documenta una transacción específica y sus documentos relacionados.
}

Objeto: PagoDto

{
"fechaPago": string,requerido
Fecha y hora en que efectivamente se recibió el pago en formato ISO 8601 (YYYY-MM-DDTHH:mm:ss). Debe ser igual o anterior a la fecha de expedición del comprobante.
Formato: date-time
"formaDePagoP": string,requerido
Clave de la forma de pago del pago según el catálogo c_FormaPago del SAT (ejemplo: 01 - Efectivo, 03 - Transferencia electrónica, 04 - Tarjeta de crédito).
"monedaP": string,requerido
Clave de la moneda en la que se recibió el pago según el catálogo c_Moneda del SAT (ejemplo: MXN, USD, EUR).
"tipoCambioP": number,opcional
Tipo de cambio de la moneda del pago a pesos mexicanos (MXN). Este campo es obligatorio cuando monedaP es diferente de MXN y XXX. Debe corresponder al tipo de cambio oficial publicado por Banxico para la fecha del pago.
"monto": number,requerido
Monto total del pago recibido, expresado en la moneda indicada en monedaP. Debe ser mayor a cero y coincidir con la suma de los importes pagados de los documentos relacionados.
"numOperacion": string,opcional
Número de operación, cheque, referencia SPEI o identificador de la transacción bancaria que respalda el pago (opcional pero recomendado para trazabilidad).
Longitud máxima: 100 caracteres
"tipoCadPago": string,opcional
Clave del tipo de cadena de pago según el catálogo c_TipoCadenaPago. Este campo es obligatorio cuando la forma de pago es SPEI (03) y se cuenta con el comprobante de pago emitido por la institución bancaria.
"certPago": string,opcional
Certificado del comprobante de pago proporcionado por la institución financiera, codificado en Base64. Obligatorio cuando se especifica tipoCadPago.
"cadPago": string,opcional
Cadena original del comprobante de pago generado por la institución financiera. Obligatorio cuando se especifica tipoCadPago.
"selloPago": string,opcional
Sello digital del comprobante de pago emitido por la institución financiera. Obligatorio cuando se especifica tipoCadPago.
"documentosRelacionados": array,requerido
Arreglo que contiene las facturas de ingreso (tipo I) que se están liquidando total o parcialmente con este pago. Debe incluir al menos un documento.
"impuestosP": objectrequerido
Nodo que contiene el desglose de impuestos trasladados y retenidos que se desprenden del pago. Debe calcularse proporcionalmente según el monto del pago aplicado a cada documento.
}

Objeto: DocumentoRelacionadoDto

{
"idDocumento": string,requerido
Folio Fiscal (UUID) de la factura de ingreso (tipo I) que se está pagando. Este UUID debe existir en el SAT y estar vigente (no cancelado).
Formato: uuid
"serie": string,opcional
Serie de la factura relacionada. Debe coincidir con la serie del CFDI original que se está pagando (opcional).
"folio": string,opcional
Folio de la factura relacionada. Debe coincidir con el folio del CFDI original que se está pagando (opcional).
"monedaDR": string,requerido
Clave de la moneda de la factura relacionada según el catálogo c_Moneda del SAT. Debe coincidir con la moneda del documento original.
"equivalenciaDR": number,opcional
Tipo de cambio entre la moneda del documento relacionado y la moneda del pago. Se calcula como: 1 unidad de moneda del documento = X unidades de moneda del pago. Solo aplica cuando las monedas son diferentes.
"numParcialidad": number,requerido
Número de parcialidad que se está pagando. Debe ser 1 para el primer pago, 2 para el segundo, y así sucesivamente. Permite el control del historial de pagos del documento.
Valor mínimo: 1
"impSaldoAnt": number,requerido
Importe del saldo insoluto de la parcialidad anterior, expresado en la moneda del documento relacionado. Para la primera parcialidad, debe ser igual al total del documento. Para parcialidades subsecuentes, es el saldo pendiente.
"impPagado": number,requerido
Importe del pago que se aplica específicamente a este documento relacionado, expresado en la moneda del documento. Debe ser menor o igual al impSaldoAnt.
"objetoImpDR": string,requerido
Clave del objeto de impuesto del documento relacionado según el catálogo c_ObjetoImp del SAT. Debe coincidir con el objetoImp del documento original (01 - No objeto de impuesto, 02 - Sí objeto de impuesto).
"impuestosDR": objectopcional
Nodo que contiene el desglose de impuestos del documento relacionado. Este nodo es obligatorio cuando objetoImpDR es 02 (Sí objeto de impuesto) y debe incluir la proporción de impuestos correspondiente al monto pagado.
}

Objeto: PagoImpuestosDto

{
"trasladosP": array,opcional
Arreglo de impuestos trasladados que se desprenden del pago (como el IVA). Cada elemento representa un tipo de impuesto trasladado con su base, tasa y monto calculado proporcionalmente.
"retencionesP": arrayopcional
Arreglo de impuestos retenidos que se desprenden del pago (como el ISR o IVA retenido). Cada elemento representa un tipo de retención con su monto calculado proporcionalmente.
}

Objeto: PagoTrasladoDto

{
"importeP": number,requerido
Monto del impuesto trasladado que corresponde proporcionalmente al pago realizado. Se calcula aplicando la tasaOCuotaP sobre la baseP.
"baseP": number,requerido
Base gravable sobre la cual se calcula el impuesto trasladado. Corresponde a la proporción del documento que se está pagando.
"impuestoP": string,requerido
Clave del tipo de impuesto trasladado según el catálogo c_Impuesto del SAT (ejemplo: 002 - IVA, 003 - IEPS).
"tipoFactorP": string,requerido
Clave del tipo de factor aplicable al impuesto según el catálogo c_TipoFactor del SAT (Tasa, Cuota o Exento).
"tasaOCuotaP": numberrequerido
Tasa o cuota del impuesto. Para IVA general es 0.160000 (16%). Debe tener 6 decimales.
}

Objeto: PagoRetencionDto

{
"impuestoP": string,requerido
Clave del tipo de impuesto retenido según el catálogo c_Impuesto del SAT (ejemplo: 001 - ISR, 002 - IVA).
"importeP": numberrequerido
Monto del impuesto retenido que corresponde proporcionalmente al pago realizado.
}

Ejemplos de Código

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": {}
}
]
}
}'

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"
}
CampoTipoDescripción
requestIdstringID único de la solicitud para trazabilidad
data.invoiceIdstring (UUID)ID interno de la factura en Lummy
data.cfdiUuidstring (UUID)UUID fiscal del SAT - Folio fiscal del CFDI timbrado
data.verificationUrlstring (URL)URL para verificar el CFDI en el portal del SAT
data.xmlUrlstring (URL)URL pública para descargar el XML timbrado
data.statusstringEstado del timbrado: stamped o pending_stamping
timestampstring (ISO)Fecha y hora de la respuesta
pathstringRuta del endpoint
methodstringMétodo HTTP de la solicitud
Generación de PDF

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"
}
CampoTipoDescripción
data.statusstringpending_stamping indica que el timbrado está en cola
data.retryInfo.nextRetryAtstring (ISO)Fecha y hora del próximo reintento automático
data.retryInfo.attemptnumberNúmero de intento actual
data.retryInfo.maxAttemptsnumberNúmero máximo de reintentos (5)
Reintentos Automáticos

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ódigoDescripción
400Datos de entrada inválidos (UUID de documento relacionado, montos, etc.)
401Token de autenticación inválido o expirado
403Sin permisos (suscripción inactiva, scope insuficiente)
404Sucursal o CSD no encontrado
409Clave de idempotencia ya usada
422Rechazo del PAC/SAT (UUID de factura relacionada no existe, saldos incorrectos)
429Rate limit excedido (máximo 30 solicitudes por minuto)
500Error interno del servidor

Errores Comunes del Complemento de Pago

Error SATDescripción
CFDI33184El UUID del documento relacionado no existe en el SAT
CFDI33185El monto pagado excede el saldo pendiente del documento
CFDI33186La suma de pagos no coincide con el monto total
CFDI33187El documento relacionado ya está completamente pagado