DEV Community

Samir Chatwiti
Samir Chatwiti

Posted on

Dominican Republic e-CF: how one tampered byte invalidates your invoice (and how to catch it)

Under Ley 32-23, the Dominican Republic requires businesses to issue Comprobantes Fiscales Electrónicos (e-CF): digitally signed XML documents transmitted to the DGII in real time. The rollout is phased by taxpayer size, and the small/medium wave is underway — which means a lot of teams are wiring e-CF generation into ERPs and billing systems right now.

Here's the thing about signed tax documents that surprises integrators: the signature freezes every byte. Touch the XML after signing — reformat it, "fix" an amount, let a proxy re-encode it — and the document is cryptographically dead, even if it still looks fine to the eye.

An experiment: falsify a real e-CF
Take a genuinely signed e-CF (type 31, Factura de Crédito Fiscal Electrónica), then do two small things a buggy pipeline could do:

change the e-NCF prefix from E31… to E32…
bump MontoTotal to a different number
Then run it through a validator that recomputes everything. Real output:

{
"valid": false,
"documentType": "31",
"signatureValid": false,
"errorCount": 2,
"warningCount": 2,
"findings": [
{ "level": "error", "ruleId": "DO-NCF-TYPE",
"text": "e-NCF type digits '32' do not match TipoeCF '31'.",
"location": "IdDoc/eNCF" },
{ "level": "error", "ruleId": "DO-MATH-TOTAL",
"text": "MontoTotal (999999.99) != MontoGravadoTotal + MontoExento + TotalITBIS + MontoImpuestoAdicional (637.2).",
"location": "Totales/MontoTotal" },
{ "level": "warning", "ruleId": "DO-SIG-DOC-DIGEST",
"text": "Document digest MISMATCH: signed DigestValue cBg59omGSW41xtQT7Q4nL54/Ueq6UObAEfP+/gf1aYg= does not match the recomputed SHA-256. The document content differs from what was signed, or a different canonicalization was used.",
"location": "ds:Reference[@uri='']" }
]
}
Three independent layers caught it: the e-NCF consistency rule, the ITBIS/totals math, and the signature digest — the recomputed SHA-256 of the document no longer matches what was signed.

That last one is the check most homemade validators skip, because it requires re-canonicalizing the XML exactly as the signer did (enveloped transform, inclusive C14N) before hashing. Skip it, and your pipeline will happily emit documents the DGII will reject.

Running the check yourself
The output above comes from the Dominican Republic e-CF Validator (DGII) — a keyless REST API (free tier available). One call:

curl --request POST \
--url https://dominican-republic-e-cf-validator-dgii.p.rapidapi.com/validate \
--header 'Content-Type: application/xml' \
--header 'x-rapidapi-host: dominican-republic-e-cf-validator-dgii.p.rapidapi.com' \
--header 'x-rapidapi-key: YOUR_RAPIDAPI_KEY' \
--data-binary @ecf.xml
It checks the e-CF v1.0 structure (XSD), DGII code lists, the e-NCF number and its consistency with the document type, ITBIS/totals reconciliation, and the full enveloped signature — document digest and RSA-SHA256 SignatureValue against the embedded certificate. On an untampered, genuinely signed e-CF it returns "valid": true, "signatureValid": true.

Keyless and stateless: no DGII account, no certificate upload, the document is validated in-memory and discarded. That makes it safe to run from CI on every generated document, not just in production.

Practical takeaways
Sign last. Any serialization step after signing (pretty-printing, encoding changes, namespace "cleanup") kills the digest.
Validate at generation time — assert on ruleIds (DO-STRUCT-, DO-NCF-, DO-MATH-, DO-SIG-) in your test suite.
Don't trust "it parses" as "it's valid". XML well-formedness says nothing about e-NCF consistency, ITBIS math, or the signature.
Scope note: a keyless pre-flight can't verify the trust chain to a DGII/INDOTEL-recognized CA or perform the real-time submission — valid: true means "ready to submit", not "accepted by the DGII".

I maintain validators like this for five mandated e-invoicing regimes (Malaysia, Dominican Republic, Nigeria, Bolivia, Costa Rica) — overview with links: github.com/SamirChatwiti/e-invoice-validators.

Top comments (0)