CFDI (cfdi v4.0.1)

Copy Markdown

Orquestador principal del CFDI 4.0.

Recibe un %Cfdi.Comprobante{} previamente armado con sus elementos (Emisor, Receptor, Conceptos, …), lo certifica, sella y serializa a XML, mapa o JSON.

Summary

Functions

Devuelve la cadena original guardada por sellar/3, o nil si todavía no fue sellado.

Asocia certificado y número de certificado al comprobante.

Genera la cadena original aplicando el XSLT al XML del CFDI.

Firma la cadena original con la llave privada cargada desde archivo.

Firma la cadena original y escribe el atributo Sello usando una credencial ya cargada en config[:credential] y la cadena en config[:cadena].

Genera la cadena original, la firma con la llave privada del archivo dado, guarda la cadena en config[:cadena_original] y escribe el atributo Sello.

Serializa el CFDI a JSON.

Proyecta el CFDI a un mapa.

Serializa el CFDI a XML respetando el orden de elementos que exige el Anexo 20 del SAT (indispensable para que los XSLT de cadena original procesen el documento correctamente).

Asocia la ruta del XSLT que generará la cadena original.

Types

t()

@type t() :: %CFDI{comprobante: Cfdi.Comprobante.t() | nil, config: map()}

Functions

cadena_original(cfdi)

@spec cadena_original(t()) :: String.t() | nil

Devuelve la cadena original guardada por sellar/3, o nil si todavía no fue sellado.

Espejo del getter cadenaOriginal de Node.

certificar(c, cred)

@spec certificar(t(), Sat.Certificados.Credential.t()) ::
  {:ok, t()} | {:error, atom()}

Asocia certificado y número de certificado al comprobante.

generar_cadena_original(c, opts \\ [])

@spec generar_cadena_original(
  t(),
  keyword()
) :: {:ok, String.t()} | {:error, term()}

Genera la cadena original aplicando el XSLT al XML del CFDI.

Espejo de generarCadenaOriginal de Node. Toma el XSLT desde config[:xslt] (set vía xslt/2) o desde opts[:xslt].

generar_sello(cadena, keyfile, password \\ nil)

@spec generar_sello(String.t(), Path.t(), String.t() | nil) ::
  {:ok, String.t()} | {:error, term()}

Firma la cadena original con la llave privada cargada desde archivo.

Espejo de generarSello de Node.

new(comprobante)

@spec new(Cfdi.Comprobante.t()) :: t()

sellar(c)

@spec sellar(t()) :: {:ok, t()} | {:error, atom()}

Firma la cadena original y escribe el atributo Sello usando una credencial ya cargada en config[:credential] y la cadena en config[:cadena].

Para el flujo de alto nivel desde archivos, usar sellar/3.

sellar(c, credential)

sellar(c, keyfile, password)

@spec sellar(t(), Path.t(), String.t() | nil) :: {:ok, t()} | {:error, term()}

Genera la cadena original, la firma con la llave privada del archivo dado, guarda la cadena en config[:cadena_original] y escribe el atributo Sello.

Espejo de sellar(keyfile, password) de Node:

public async sellar(keyfile: string, password: string): Promise<void> {
  const cadena = await this.generarCadenaOriginal();
  const sello = await this.generarSello(cadena, keyfile, password);
  this._cadenaOriginal = cadena;
  this.setSello(sello);
}

to_json(cfdi)

@spec to_json(t()) :: String.t()

Serializa el CFDI a JSON.

Opciones:

  • :nstrue (default) incluye prefijos cfdi:; false los omite.
  • :prettytrue indenta el JSON; false (default) compacto.

to_json(cfdi, opts)

@spec to_json(
  t(),
  keyword()
) :: String.t()

to_map(cfdi)

@spec to_map(t()) :: map()

Proyecta el CFDI a un mapa.

Opciones:

  • :nstrue (default) incluye el prefijo cfdi: en los nombres de elementos y mantiene los atributos como átomos (:Rfc, :Nombre) para distinguirlos de los elementos hijos; false los omite y uniforma TODAS las llaves al tipo elegido en :keys.

  • :keys — controla el tipo de las llaves cuando ns: false. Sin efecto con ns: true (la convención manda). Valores:

    • :string (default) — todas las llaves son strings. Siempre seguro.
    • :existing — llaves se convierten a átomo si ya existe en la tabla global de átomos del VM; si no, quedan como string. Seguro ante XML/llaves arbitrarias.
    • :atom — todas las llaves se convierten a átomos vía String.to_atom/1. Peligroso con XML externo: la tabla de átomos no tiene GC y puede agotarse (atom_table_full). Usar solo cuando se controla la fuente del XML.
  • :case — controla la capitalización de las llaves cuando ns: false. Sin efecto con ns: true. Valores:

    • :as_is (default) — preserva la capitalización original (PascalCase como en el XSD oficial: NoCertificado, RegimenFiscal).
    • :camel — pasa la primera letra a minúscula para producir camelCase idiomático (noCertificado, regimenFiscal). El resto del nombre queda intacto (UsoCFDIusoCFDI, preservando el acrónimo final). Útil al exportar a JSON o sistemas JS que esperan camelCase.

Convenciones de llaves cuando ns: true:

  • strings ("cfdi:Emisor") son elementos XML.
  • átomos (:Rfc, :Nombre) son atributos XML.

Cuando ns: false, las llaves se uniforman para una vista plana — útil para inspección, serialización a JSON o consumo desde sistemas que no distinguen entre atributos y elementos.

to_map(cfdi, opts)

@spec to_map(
  t(),
  keyword()
) :: map()

to_xml(cfdi)

@spec to_xml(t()) :: String.t()

Serializa el CFDI a XML respetando el orden de elementos que exige el Anexo 20 del SAT (indispensable para que los XSLT de cadena original procesen el documento correctamente).

Opciones:

  • :prettytrue indenta el XML para lectura humana; false (default) produce XML compacto en una sola línea.

to_xml(cfdi, opts)

@spec to_xml(
  t(),
  keyword()
) :: String.t()

xslt(c, path)

@spec xslt(t(), String.t()) :: t()

Asocia la ruta del XSLT que generará la cadena original.

Espejo de options.xslt en el constructor de CFDI de Node.