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 field | Source |
|---|---|
documentTypeCode | invoice.type |
series | invoice.serie |
documentNumber | invoice.innerDocumentNumber or the number parsed from the IUD |
issueDate | invoice.issueDate |
issueTime | invoice.issueTime |
issuerTaxId | invoice.emitter.taxId.value |
issuerName | invoice.emitter.name |
issuerAddress | invoice.emitter.address.addressDetail |
issuerContact | emitter email, mobile phone, or telephone |
customerTaxId | invoice.receiver.taxId.value |
customerName | invoice.receiver.name |
customerAddress | invoice.receiver.address.addressDetail |
customerContact | receiver email, mobile phone, or telephone |
lines | invoice lines |
totals | invoice totals |
total | invoice.totals.payableAmount |
currency | always CVE when invoice is supplied |
conversion | RenderDfaOptions.conversion |
Line mapping:
| Renderer field | Source |
|---|---|
code | line.item.emitterIdentification |
description | line.item.description |
quantity | line.quantity.value |
unitCode | line.quantity.unitCode |
unitPrice | line.price |
netTotal | line.netTotal |
taxTotal | sum of line.taxes[].taxTotal |
HTTP Adapter
The adapters expose two DFA routes:
| Method | Path | Payload |
|---|---|---|
POST | /dfa | { iud, invoice?, options? } |
GET | /dfa/:iud | IUD-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:
| Option | Purpose |
|---|---|
emissionMode | Online, Offline, or Off |
contingencyIuc | Contingency IUC displayed when applicable |
title | PDF title override |
currency | Deprecated 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} CVEwith 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.