efaturaefatura
Beta

Beta documentation. APIs may change before the stable release.

DFA

DFA means Documento Fiscal Auxiliar. The package can render a PDF for local preview or application delivery through the DfaRenderer contract.

The default renderer is PdfDfaRenderer.

import { PdfDfaRenderer, createEfatura } from '@akira-io/efatura';

const efatura = createEfatura(config, {
  dfaRenderer: new PdfDfaRenderer(),
});

QR Code URL

const url = efatura.dfaQrCodeUrl(iud);

The URL is built from dfaBaseUrl and the encoded IUD. The base URL must use HTTPS.

Render From The Facade

const dfa = await efatura.renderDfa({
  iud,
  invoice,
  emissionMode: 'Online',
});

renderDfa() returns:

{
  contentType: 'application/pdf',
  filename: `${iud}.pdf`,
  buffer: Buffer
}

Input Mapping

When invoice is supplied, the package maps these fields to the renderer:

Renderer fieldSource
documentTypeCodeinvoice.type
seriesinvoice.serie
documentNumberinvoice.innerDocumentNumber or the number parsed from the IUD
issueDateinvoice.issueDate
issueTimeinvoice.issueTime
issuerTaxIdinvoice.emitter.taxId.value
issuerNameinvoice.emitter.name
issuerAddressinvoice.emitter.address.addressDetail
issuerContactemitter email, mobile phone, or telephone
customerTaxIdinvoice.receiver.taxId.value
customerNameinvoice.receiver.name
customerAddressinvoice.receiver.address.addressDetail
customerContactreceiver email, mobile phone, or telephone
linesinvoice lines
totalsinvoice totals
totalinvoice.totals.payableAmount
currencyalways CVE when invoice is supplied
conversionRenderDfaOptions.conversion

Line mapping:

Renderer fieldSource
codeline.item.emitterIdentification
descriptionline.item.description
quantityline.quantity.value
unitCodeline.quantity.unitCode
unitPriceline.price
netTotalline.netTotal
taxTotalsum of line.taxes[].taxTotal

HTTP Adapter

The adapters expose two DFA routes:

MethodPathPayload
POST/dfa{ iud, invoice?, options? }
GET/dfa/:iudIUD-only render

POST /dfa validates invoice before rendering when invoice data is present.

await fetch('/efatura/dfa', {
  method: 'POST',
  credentials: 'include',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    iud,
    invoice,
    options: {
      title: 'Documento Fiscal Auxiliar',
    },
  }),
});

Supported options:

OptionPurpose
emissionModeOnline, Offline, or Off
contingencyIucContingency IUC displayed when applicable
titlePDF title override
currencyDeprecated compatibility field; only CVE is accepted

The HTTP schema rejects conversion metadata. Currency preparation and provenance remain a trusted facade concern in this release. Server code can prepare and render directly through Efatura, or expose an application-owned authenticated endpoint with a server-selected provider.

Currency Conversion Evidence

DFE and DFA fiscal amounts are always CVE. For a prepared foreign-currency invoice, pass the returned invoice and conversion metadata together:

const prepared = await efatura.prepareInvoiceToCve(invoiceInEur, {
  sourceCurrency: 'EUR',
});

const dfa = await efatura.renderDfa({
  iud,
  invoice: prepared.invoice,
  conversion: prepared.conversion,
});

The default PDF renderer shows:

  • the original payable amount and source currency;
  • the rate as 1 {sourceCurrency} = {rate} CVE with up to five fractional digits;
  • the quote effective date;
  • the provider name;
  • the source URL when present.

Conversion evidence paginates when it does not fit below the totals. Persist prepared.invoice and prepared.conversion, and use the stored values for reprints. Fetching a second quote could make the DFA disagree with the signed DFE.

Before rendering, direct conversion metadata is checked against the invoice. The invoice must contain totals, the target must be CVE, and the converted payable amount must equal both the invoice payable amount and the original payable amount multiplied by the normalized rate with two-decimal half-up rounding. Foreign original value, currency, and rate must equal the sole alternative payable amount. A mismatch throws EfaturaValidationError with code dfa.conversion_invalid.

Deprecated Currency Label

RenderDfaOptions.currency is deprecated and will be removed in v1.0.0. It relabeled values without converting them and could produce a misleading fiscal document.

When currency is defined, the package emits a Node.js DeprecationWarning once per process with code EFATURA_RENDER_DFA_CURRENCY_DEPRECATED. The warning occurs before legacy validation. When invoice is present, renderer input is fixed to CVE and the legacy label is ignored. When rendering by IUD alone, currency: 'CVE' remains accepted during the compatibility period; another value emits the warning and then throws EfaturaValidationError with code dfa.currency_invalid. Omitting currency emits no warning.

Remove currency. For foreign invoices, use prepareInvoiceToCve() and pass its prepared invoice plus conversion. See Currency Conversion for the migration flow.

Pagination

The PDF renderer paginates item rows. The regression test covers 24 lines and asserts that the document uses more than one page instead of dropping rows.

Use a sample with more lines when testing invoice layouts manually. See Fastify Invoice Payload.

Custom Renderer

Implement DfaRenderer when the application needs a branded layout:

import type { DfaDocument, DfaRenderInput, DfaRenderer } from '@akira-io/efatura';

class BrandedDfaRenderer implements DfaRenderer {
  async render(input: DfaRenderInput): Promise<DfaDocument> {
    return {
      contentType: 'application/pdf',
      filename: `${input.iud}.pdf`,
      buffer: await renderPdf(input),
    };
  }
}

DfaRenderInput.conversion is optional CurrencyConversionMetadata. When present, keep the original amount, source currency, normalized rate direction, effective date, provider, and optional source URL visible with the QR code URL, IUD, issuer, customer, line, tax, total, and contingency fields.