El mismo endpoint
El REP se timbra con POST /invoice/create, igual que una factura: TipoDeComprobante "P" y el complemento en Complemento.Pagos20.
Cuando tu cliente paga una factura PPD, envías el recibo electrónico de pago (Pagos 2.0) en JSON y recibes el CFDI timbrado, ultrarrápido y válido ante el SAT, con su XML y su PDF. Es el mismo endpoint y la misma llave que usas para facturar; cada REP timbrado usa 1 folio.
Todo lo que lleva un complemento de pago 2.0, desde tu sistema de cobranza o tu ERP.
El REP se timbra con POST /invoice/create, igual que una factura: TipoDeComprobante "P" y el complemento en Complemento.Pagos20.
Cada Pago lleva sus DoctoRelacionado con NumParcialidad, ImpSaldoAnt, ImpPagado e ImpSaldoInsoluto. Un REP puede saldar varias facturas y registrar varios pagos.
ImpuestosDR por documento, ImpuestosP por pago y los Totales del complemento: IVA al 16%, al 8% y al 0%, exento y retenciones.
En un REP, la API quita FormaPago y MetodoPago del comprobante antes de timbrar.
Al timbrar, el REP queda relacionado con las facturas de tu cuenta que salda. GET /invoice/relations te muestra esa relación.
Con enviar_mail en el JSON, el REP se envía por correo a tu cliente en cuanto se timbra.
Tu cliente pagó por transferencia una factura de $1,000.00 más IVA. El JSON va en el campo json de POST /invoice/create, con tu llave en el header X-Api-Key.
# FD_API=https://sandbox-app.facturadigital.com.mx/api/v5
curl -X POST "$FD_API/invoice/create" \
-H "X-Api-Key: $FD_API_KEY" \
--data-urlencode "json@recibo-de-pago.json"{
"Version": "4.0",
"Serie": "P",
"Folio": "AUTO",
"Fecha": "AUTO",
"SubTotal": "0",
"Moneda": "XXX",
"Total": "0",
"TipoDeComprobante": "P",
"Exportacion": "01",
"LugarExpedicion": "64000",
"Emisor": { "RegimenFiscal": "601" },
"Receptor": {
"Rfc": "XIA190128J61",
"Nombre": "XENON INDUSTRIAL ARTICLES",
"DomicilioFiscalReceptor": "76343",
"RegimenFiscalReceptor": "601",
"UsoCFDI": "CP01"
},
"Conceptos": [{
"ClaveProdServ": "84111506",
"Cantidad": "1",
"ClaveUnidad": "ACT",
"Descripcion": "Pago",
"ValorUnitario": "0",
"Importe": "0",
"ObjetoImp": "01"
}],
"Complemento": {
"Pagos20": {
"Totales": {
"TotalTrasladosBaseIVA16": "1000.00",
"TotalTrasladosImpuestoIVA16": "160.00",
"MontoTotalPagos": "1160.00"
},
"Pago": [{
"FechaPago": "2026-09-22T12:00:00",
"FormaDePagoP": "03",
"MonedaP": "MXN",
"TipoCambioP": "1",
"Monto": "1160.00",
"DoctoRelacionado": [{
"IdDocumento": "0B7C2E51-8A4D-4E0F-A1C3-7D9E6F2B5A10",
"Serie": "F",
"Folio": "2231",
"MonedaDR": "MXN",
"EquivalenciaDR": "1",
"NumParcialidad": "1",
"ImpSaldoAnt": "1160.00",
"ImpPagado": "1160.00",
"ImpSaldoInsoluto": "0.00",
"ObjetoImpDR": "02",
"ImpuestosDR": {
"TrasladosDR": [{
"BaseDR": "1000.00",
"ImpuestoDR": "002",
"TipoFactorDR": "Tasa",
"TasaOCuotaDR": "0.160000",
"ImporteDR": "160.00"
}]
}
}],
"ImpuestosP": {
"TrasladosP": [{
"BaseP": "1000.00",
"ImpuestoP": "002",
"TipoFactorP": "Tasa",
"TasaOCuotaP": "0.160000",
"ImporteP": "160.00"
}]
}
}]
}
},
"enviar_mail": {
"destinatarios": "cliente@facturadigital.com.mx"
}
}{
"message": "The document was generated successfully",
"code": 200,
"cfdi": {
"UUID": "6FA90F39-2D7A-4F1C-9B3E-5C1D8A0E7B42",
"FechaTimbrado": "2026-09-22T12:04:31",
"XmlBase64": "PD94bWwgdmVyc2lvbj0iMS4wIi...",
"PDF": "https://app.facturadigital.com.mx/docs/pdf/6FA90F39-...",
"XML": "https://app.facturadigital.com.mx/docs/xml/...",
"Serie": "P",
"Folio": "318",
...
}
}De la factura PPD al REP timbrado.
La factura original lleva MetodoPago PPD y FormaPago 99. Guarda su UUID: será el IdDocumento del REP.
Para usar Folio "AUTO", da de alta una serie para el tipo de comprobante P en Configuración → Series y Folios.
Por cada pago: fecha, forma de pago, monto y los documentos que salda, con su parcialidad, saldo anterior, importe pagado y saldo insoluto.
Llama a POST /invoice/create y guarda UUID, Serie y Folio de la respuesta. Con enviar_mail, el REP le llega a tu cliente.
Los errores responden con HTTP 400 y un code en el cuerpo. Si el REP no se timbra, no se usa folio.
Timbra CFDI de ingreso y traslado con el complemento Carta Porte y las reglas del SAT revisadas antes de timbrar.
Cancela un REP o una factura con motivos 01 a 04 y recibe el acuse del SAT. Cancelar no usa folio.
Qué es el REP, cuándo se emite y cómo se registra un pago desde la app.
Ambiente de pruebas gratis con la misma API v5 que producción.
Que tu sistema se entere de lo que pasa en tu cuenta sin consultar la API.
Autenticación, endpoints y las tres formas de timbrar: JSON, XML en Base64 o archivo XML.
¿Algo que no está aquí? Escríbenos o revisa la referencia completa.
POST /invoice/create, el mismo que para una factura. Mandas TipoDeComprobante "P" y el complemento en Complemento.Pagos20; la respuesta es la misma: UUID, XML en Base64 y ligas al PDF y al XML.
Sí. Cada CFDI timbrado usa 1 folio, también el REP. La API está incluida: pagas folios, no la API, y los folios no caducan.
Sí. Cada Pago acepta varios DoctoRelacionado y el complemento acepta varios Pago. Los importes de todo el complemento van en Pagos20.Totales.
No. Los mandas tú: ImpSaldoAnt, ImpPagado e ImpSaldoInsoluto por documento, y los Totales del complemento. La API arma el XML, quita FormaPago y MetodoPago, lo valida contra el esquema del SAT y lo timbra.
Con GET /invoice/relations y el UUID de la factura en el header Uuid. En padres vienen los CFDI que la relacionan, incluidos los REP timbrados en tu cuenta.
Sí. Agrega enviar_mail al JSON con destinatarios (y, si quieres, bcc y mensaje) y el REP se envía en cuanto se timbra. En el sandbox los correos no les llegan a tus clientes: se desvían a un buzón de pruebas.
Sí. Envíalo sellado a /invoice/stampxml (Base64) o a /invoice/stampxmlfile (archivo). Estos dos endpoints no agregan el documento a tus listados de la API.
Es gratis y usa la misma API v5 que producción. Cuando funcione, cambias la URL base y la llave.