API DE CFDI DE RETENCIONES

Timbra retenciones desde tu propio sistema

Un POST con el JSON del comprobante y te regresamos el UUID timbrado. Sin instalar nada, sin capturar a mano y sin depender del portal del SAT.

¿Qué es el CFDI de retenciones e información de pagos?

Es el comprobante que emites cuando le retienes un impuesto a alguien: ISR a un profesionista independiente, IVA a un arrendador, el impuesto sobre dividendos que reparte tu empresa, o lo que retienes al pagarle a un residente en el extranjero. No es una factura de ingresos — es un documento aparte, con su propio esquema XML y su propio catálogo de claves.

La versión vigente es la 2.0, y si estás leyendo esto probablemente ya sepas la parte fiscal. Lo que sigue es la parte que te falta: cómo emitirlo desde tu código.

El endpoint

Ojo con este detalle, porque es donde se atora casi todo el mundo la primera vez: las retenciones 2.0 no cuelgan de la misma ruta que el resto de CFDI. Van a su propio recurso.

POSThttps://apisandbox.facturama.mx/2/retenciones

Ese es el host de pruebas. En producción es el mismo path cambiando el dominio a apisandbox.facturama.mx. La autenticación es HTTP Basic con las credenciales de tu cuenta — nada de OAuth ni de refrescar tokens cada hora.

El body que mandas

Este es un comprobante real de retención de ISR e IVA por servicios profesionales, con el RFC de pruebas del SAT:

{
    "FolioInt": "0001",
    "FechaExp": "2022-06-13T08:08:01",
    "CveRetenc": "01",
    "LugarExpRetenc": "26015",
    "Emisor": {
        "RFCEmisor": "EKU9003173C9",
        "NomDenRazSocE": "ESCUELA KEMPER URGATE",
        "RegimenFiscalE": "601"
    },
    "Receptor": {
        "Nacionalidad": "Nacional",
        "Nacional": {
            "RFCRecep": "CACX7605101P8",
            "NomDenRazSocR": "XOCHILT CASAS CHAVEZ",
            "DomicilioFiscalR": "10740"
        }
    },
    "Periodo": {
        "MesIni": "01",
        "MesFin": "01",
        "Ejerc": "2021"
    },
    "Totales": {
        "montoTotOperacion": "1681.06",
        "montoTotGrav": "1681.06",
        "montoTotExent": "0.00",
        "montoTotRet": "151.29",
        "ImpRetenidos": [
            {
                "BaseRet": "1681.06",
                "Impuesto": "01",
                "MontoRet": "16.81",
                "TipoPagoRet": "04"
            },
            {
                "BaseRet": "268.96",
                "Impuesto": "02",
                "MontoRet": "134.48",
                "TipoPagoRet": "01"
            }
        ]
    }
}

Fíjate en el arreglo ImpRetenidos: ahí va un objeto por cada impuesto que retienes. En el ejemplo hay dos. El primero es el 1% de ISR sobre los $1,681.06 de la operación. El segundo es IVA: la base son $268.96 (el 16% de la operación) y se retienen $134.48, o sea las dos terceras partes redondeadas. Esa aritmética la tienes que resolver tú antes de mandar el JSON — la API no la calcula por ti.

Campos que no puedes omitir: FechaExp, CveRetenc, LugarExpRetenc, el nodo Emisor completo (RFCEmisor, NomDenRazSocE, RegimenFiscalE), Periodo, Totales y —si el receptor es nacional— su RFCRecep, NomDenRazSocR y DomicilioFiscalR. Todo lo demás es opcional.

Lo que te regresa

Si el timbrado salió bien, la respuesta trae tu comprobante más los campos que genera el proceso de certificación. Los tres que te van a interesar guardar en tu base de datos:

  • Id — el identificador interno. Lo necesitas para consultar, descargar o cancelar después.
  • Complemento.TimbreFiscalDigital.UUID — el folio fiscal, lo que todo el mundo llama "el UUID".
  • CadenaOriginal y Sello — por si tienes que auditar o revalidar el comprobante.

También viene IsCanceled, que en una emisión nueva siempre llega en false. Sirve más adelante, cuando consultas.

Retenciones con complemento

El comprobante base sirve para las retenciones sencillas. Pero según el tipo de pago, el SAT te pide además un complemento con datos específicos — y ahí es donde el esquema se pone interesante.

Los que soporta el estándar de retenciones 2.0:

  • Dividendos o utilidades distribuidas
  • Pagos a residentes en el extranjero
  • Intereses
  • Intereses hipotecarios
  • Enajenación de acciones
  • Premios
  • Arrendamiento en fideicomiso
  • Fideicomiso no empresarial
  • Planes de retiro
  • Operaciones con derivados
  • Sector financiero
  • Servicios mediante plataformas tecnológicas

Dos de estos tienen su propia página con el detalle de implementación: el complemento de intereses —el que usan bancos, fintechs y casas de bolsa para las constancias anuales— y el de servicios por plataformas tecnológicas, obligatorio si operas un marketplace o una app que le paga a repartidores, conductores o anfitriones.

La clave que va en CveRetenc sale del catálogo c_CveRetenc del SAT, que va del 01 al 26. La 26, por ejemplo, es la de servicios mediante plataformas tecnológicas. Conviene que la leas del catálogo vigente publicado por el SAT en vez de quemarla en el código: cambia con cada actualización del Anexo 20.

Lo demás que vas a necesitar

Emitir es solo el primer día. Tarde o temprano llega la llamada de "oye, ¿me reenvías la constancia?" o el "hay que cancelar esa". Todo eso también está en la API:

GET/api/Retenciones/{id}

Con el Id que guardaste al emitir, recuperas el detalle completo del comprobante. Y desde ahí puedes filtrar por intervalos, descargar el XML o el PDF, mandarlo por correo al receptor y cancelarlo.

Un apunte sobre FolioInt en la 2.0: acepta numérico de 1 a 10 caracteres, o alfanumérico de 1 a 20. Si piensas consultar por intervalo de folios más adelante, usa el formato numérico desde el principio — con folios alfanuméricos esa consulta no te va a funcionar. Es de esas decisiones que parecen menores el día uno y duelen a los seis meses.

SDKs, por si no quieres armar los requests a mano

Hay librerías oficiales para PHP, Python, JavaScript, Java, Ruby y .NET (4.5 en adelante), todas con su repositorio en GitHub. Envuelven la autenticación y el serializado del JSON, que es la parte aburrida.

Dicho esto: la API es REST plano con Basic Auth. Si tu stack no está en esa lista o simplemente prefieres controlar tú los requests, con el cliente HTTP de tu lenguaje te sobra. No hay nada propietario en el protocolo.

Cómo empezar a probar

  1. Crea tu cuenta y pide acceso al sandbox. Ahí timbras contra apisandbox.facturama.mx sin gastar folios y sin necesidad de tu CSD real.
  2. Copia el JSON de arriba tal cual y mándalo. Usa el RFC de pruebas EKU9003173C9, que es el que el SAT publica para este fin.
  3. Cuando el sandbox te devuelva un UUID, cambia el host a apisandbox.facturama.mx, carga tu Certificado de Sello Digital y ya estás emitiendo en real.
Para timbrar en producción necesitas folios de API. Son distintos de los folios de la plataforma web — revísalo antes de programar el pase a producción un viernes.

¿Y si no quieres programar nada?

Si emites pocas retenciones al mes, integrar la API probablemente no te compensa. Puedes generarlas desde la plataforma web de Facturama llenando un formulario, y te ahorras el desarrollo completo.

La API tiene sentido cuando el volumen crece o cuando la retención tiene que salir sola —al cerrar un periodo, al liquidar a tus proveedores, al pagarle a los usuarios de tu plataforma— sin que nadie se acuerde de entrar a capturarla.

Ver el Módulo de Retenciones de la plataforma web

Preguntas frecuentes

¿El CFDI de retenciones lleva UUID?

Sí. Se timbra igual que cualquier CFDI y la respuesta trae su TimbreFiscalDigital con el folio fiscal. Es un comprobante certificado, no un documento informativo.

¿Puedo cancelar una retención ya timbrada?

Sí, con el Id del comprobante. El campo IsCanceled que devuelve la consulta te dice en qué estado está.

¿Sirve para pagos a residentes en el extranjero?

Sí. En el nodo Receptor cambias Nacionalidad y usas Extranjero con NumRegIdTrib en lugar del RFC. Es el caso típico de regalías, servicios contratados fuera de México o intereses pagados a un no residente.

¿Cuál es la diferencia entre /2/retenciones y /api/Retenciones?

La primera es la versión 2.0 del estándar, que es la vigente y la que debes usar en desarrollos nuevos. Los endpoints de consulta y detalle siguen colgando de /api/Retenciones.

¿Necesito un PAC aparte?

No. Facturama trabaja con PACs —Proveedores Autorizados de Certificación— y el timbrado va incluido en la misma llamada. Tú mandas el JSON, nosotros nos encargamos de la certificación.

Empieza por el sandbox

No cuesta nada y en una tarde sabes si la integración te sirve. Si te atoras, el soporte técnico lo da gente que ha implementado la API, no un chatbot.

Crear cuenta y probar Hablar con un ingeniero