Home / Blog / Tutorials / Test CFE 25-1 in Odoo
TutorialsUruguay

Test CFE 25-1: is your Odoo ready for the new DGI format?

How to test your Odoo against DGI Uruguay's homologación environment before a buyer calls asking about the first RECHAZADO.

Sergei Filatov
Sergei FilatovFounder · data-metrics.pro · May 27, 2026
◷ 11 min read

One-minute summary

On March 3, 2026, Uruguay's DGI closed the CFE 24 format and made 25-1 the only valid version in production. Nearly three months in, a meaningful share of Uruguayan SMBs are still emitting CFEs that DGI rejects at validation — not out of bad faith, but because their Odoo install never went through the test the regulator leaves open 24/7 in the homologación environment.

If you're a director, controller, or SMB owner and your Odoo has emitted even one CFE since March 3, this test belongs on your monthly checklist. Not "at some point": now, against the scenarios DGI itself publishes, before a buyer calls asking where their invoice is.

This piece walks through how to run that test against CFE 25-1, what DGI validates under the hood, where most community installs stumble, and which l10n_uy settings to touch so you stop collecting RECHAZADO. No filler — references to official sources and real cases from April and May 2026.

  • CFE 25-1 is mandatory as of March 3, 2026. DGI no longer accepts the prior format for production emissions.
  • DGI's homologación environment runs 24/7. Any emisor can rehearse scenarios before pushing to production.
  • Six key checks in the test: credit-note linkage to the original CFE, GTIN/EAN for retail, VUCE logistics fields for exports, correct use of Sales Mode 91, BCU exchange-rate validation for multi-currency, and consistent tributos for Monotributo / IVA mínimo.
  • The community l10n_uy module shipped 25-1 support in February 2026 — two to three months late, right on top of the deadline.
  • DGI fines for invalid CFEs land in the UY$ 4,000–UY$ 36,000 range per incident. Repeat offenders risk emisor-status suspension.
i
If you haven't read the broader picture, start with the DGI CFE 25-1 pillar guide; this piece zooms in on the technical test.

Context: why 25-1 is not cosmetic

CFE launched in Uruguay back in 2012 and is one of LATAM's oldest e-invoicing systems. Through 2024 the changes were cosmetic. Version 25-1 is the first structural overhaul in five years, and it has three drivers behind it.

  • Integration with VUCE (the single-window customs portal) for traceability on export operations.
  • Alignment with GS1 Uruguay on retail standards (GTIN/EAN moves from optional to required).
  • Closing the grey-zone usage of credit notes, historically used to inflate deductions; the cryptographic link to the original CFE is now mandatory.

The timeline that matters fits in four rows.

DateMilestone
Q3 2024DGI publishes the 25-1 draft
Aug 1, 2025Homologación environment opens to emisores
Mar 3, 2026Production deadline: prior format is out
Q2 2026First wave of rejections among SMBs that skipped testing

What changed underneath is XML structure that DGI parses with zero tolerance. If a field is missing or the format is off, the endpoint returns <RESULTADO>RECHAZADO</RESULTADO> and the document has no legal standing.

  1. Credit notes — mandatory reference to the original CFE: type, series, number, amount, currency, and date. DGI validates the match across all five fields.
  2. GTIN/EAN — for retail CFE (Tipo 101 and 111), the GS1 code is no longer optional.
  3. Export logistics fields — DUA, customs-yard code, transport mode. All forwarded to VUCE automatically.
  4. Sales Mode 91 — Mandating Export — new code for the "Uruguayan exporter selling through a commercial intermediary" case. Previously encoded as plain export.
  5. Third-party CFE ban for emisores on IVA mínimo, Monotributo, and MIDES CAE: they cannot emit CFEs on behalf of other companies.
  6. Multi-currency exchange rate — mandatory use of the BCU rate from the emission date. DGI used to accept any source.

How Odoo gets ready: 6 technical checks

Any Odoo install that emits CFE has to clear six checks before touching production. Here they are, in order of impact.

#1. Correct version of l10n_uy

OCA maintains l10n_uy_accountl10n_uy_invoiceand l10n_uy_cfeThe 25-1 update shipped in February 2026 — right up against the deadline. If you run Odoo 16 or 17 community with l10n_uy older than that, your XML is generated against the old schema.

How to check: Settings → Apps → Installed → l10n_uy*Latest version column. If the apply date is before February 15, 2026, upgrade now. Odoo Enterprise via partner channel receives the update automatically — but only when the maintenance contract is active, and that lapses more often than people expect.

#2. Electronic signature certificate

The certificate must come from a CCA accredited by the UCEFor 25-1 the DGI accepts certificates from El Correo Uruguayo, Abitab, and El País Digital. Older certificates from now-unaccredited CAs are rejected at handshake.

How to check: Accounting → Configuration → Companies → Electronic Invoice → Certificate expiration. If it expires in the next 90 days, renew early — state-CA renewal takes 5–10 business days.

#3. DGI WebService connection

DGI receives CFEs over SOAP. In 25-1 the endpoints changed: production and homologación now live on different ports and paths. If your config still points to the old endpoint, every request times out or fails on a TLS handshake.

This is a common trap: l10n_uy_cfe.cfg keeps the old default hard-coded and doesn't refresh automatically on module upgrade.

#4. Document-type configuration

CFE 25-1 distinguishes basic document types strictly.

TipoDescriptionWhen it applies
101e-TicketRetail, B2C
111e-FacturaB2B, general case
121e-Factura ExportaciónExport
131e-RemitoGoods shipment
141e-ResguardoTax withholding
151e-Factura CréditoCredit notes
181e-Boleta de ContadoCash payment

If you emit generic out_invoice without an explicit mapping to l10n_uy.document.type, DGI rejects on the first request.

#5. VUCE integration fields (export)

For Tipo 121 (e-Factura Exportación) in 25-1, these fields are required.

  • DUACode — DUA number (Documento Único Aduanero).
  • MTransporte — transport mode (1=Sea, 2=Air, 3=Land, 4=Rail, 5=Postal, 8=Multimodal).
  • CodPaisDest — destination country in ISO 3166-1 alpha-2.
  • Incoterm — ICC 2020 standard.

The stock l10n_uy_cfe module doesn't surface these on the invoice form. You'll need either a custom patch or the OCA l10n_uy_export module from the l10n-uruguay repo (March 2026 release).

#6. Multi-currency exchange rate

When emitting a CFE in foreign currency, Odoo pulls the rate from Configuration → Currencies → RatesWith 25-1, DGI requires the BCU rate from the emission date — not yesterday's, not a monthly average. If automatic rate sync is off (community default), every export CFE goes out with a validation error.

!
Non-obvious gotcha. The l10n_uy upgrade ships a script that adjusts the schema but does not re-map old taxes, partners, or products. A clean migration clears all six checks in homologación; a rushed one clears only #1 and reveals the other five in production. Budget half a day for the post-upgrade data audit.

Real scenarios: when the test passes and when it doesn't

Four typical Uruguayan-SMB situations from April and May 2026, in growing order of difficulty.

#1. Passes: retail store with a single till, Odoo 17 Enterprise

One location, e-Ticket only (Tipo 101), products with GTIN loaded into product.template.barcode, single currency UYU. The partner upgraded l10n_uy on February 20, 2026. The test passes across all scenarios with no custom patches: 5 homologación scenarios and an hour of work suffice.

#2. Passes with tweaks: B2B importer with multi-currency

You import goods, emit e-Factura (Tipo 111) in UYU and USD, occasionally e-Resguardo (Tipo 141) on withholdings. Odoo 17 Community with l10n_uy from February 2026. You need to turn on BCU automatic rate sync, map account.tax to Uruguayan tributos (IVA Básica 22%, IVA Mínima 10%, IRAE Anticipo), and double-check that partner.l10n_uy_cfe_doc_type has the right type (RUT/CI/Pasaporte) on every contact. The test passes after 2–4 hours of tuning.

#3. Doesn't pass: exporter without l10n_uy_export

You emit Tipo 121, sell through a commercial intermediary in Brazil (Sales Mode 91), and run Odoo Community with base l10n_uy. You're missing the VUCE fields (DUA, MTransporte, Incoterm), the Sales Mode 91 logic, and the link to the TUPA customs-regime code. DGI rejects every attempt. The fix is custom development or moving to Enterprise plus the l10n_uy_export module. Realistic timeline: 2–4 weeks of work.

#4. Doesn't pass: Monotributista using someone else's Odoo

You're a Monotributista and your accountant "let you in" to their Odoo so you can emit CFEs through their emisor. With 25-1 this is prohibited: every Monotributista needs their own emisor registration with DGI. No test will pass because the rejection happens at the RUT validation stage, before the schema is even evaluated. The fix is to register as an independent emisor (free via DGI e-Factura) and connect your own Odoo or use a multicompany setup.

The 5 most expensive mistakes

#1. "We'll fix it when the first one bounces"

The default SMB reflex is to wait until DGI rejects a CFE and then react. The problem: in Uruguay a rejection means the document has no legal standing even though the goods already shipped. The customer can't pay because there's no valid CFE, accounting can't close the period, and DGI adds late fees every day. The right move is running at least 20 scenarios in homologación before the first production emission.

#2. "We upgraded the module, all good"

Upgrading l10n_uy changes the XML schema but doesn't reconfigure existing data. Products without GTIN, contacts with the wrong RUT type, and taxes without mapping stay the way they were. The test fails on the first e-Ticket. After every upgrade, run a short data audit on products, partners, taxes, and currencies.

#3. Using the homologación certificate in production

DGI issues two separate certificates: test and prod. It's common to leave Odoo with the test certificate, after which every prod request fails with the signature flagged as "not valid for production". Keep test and prod in separate databases and never cross certificates.

#4. Credit notes without a reference to the original

In Odoo, Refund Invoice creates the credit note automatically but doesn't always fill referencia_documento_original — especially when the original was emitted before the upgrade. DGI rejects the note and you lose deductibility. Manually check the first post-migration credit note: Logs → CFE XML → <Referencia> block.

#5. Ignoring Sales Mode 91 on exports via an intermediary

Older export CFEs went out as Sales Mode 1 (direct export). With 25-1, when there's a commercial intermediary the code is 91. Leave it as 1 and DGI accepts the CFE, but the operation never shows up in the VUCE declaration — and customs blocks the next shipment. It's a mistake you discover late and pay for.

Anonymous case: a textile exporter from Canelones

Anonymized case based on a typical situation we reviewed with a Montevideo accountant in April 2026.

The setup. A knitwear manufacturer exporting to Brazil and Argentina through a commercial agent in São Paulo. Volume: ~USD 2.5M/year, about 300 export CFEs per year. Odoo 16 Enterprise, base l10n_uyno l10n_uy_export. The partner upgraded the module on March 1, 2026 — two days before the production deadline.

What the test surfaced. A 15-scenario homologación run on March 5 produced this picture.

  • 12 of 15 e-Factura Exportación (Tipo 121) — RECHAZADO, missing DUACode and MTransporte.
  • 3 of 3 with Sales Mode 91 — RECHAZADO, the field never made it into the XML.
  • 5 of 5 e-Resguardo (Tipo 141) for IRAE withholding — accepted; the problem was scoped to the export block.

What we did. Three steps over 12 business days.

  1. Installed the OCA l10n_uy_export module (beta on March 5, stable on March 18).
  2. Added partner-level custom fields for the commercial intermediary (Sales Mode mapping).
  3. Pre-set Incoterm FOB Montevideo as the automatic default on every export line.

30-day result. All e-Factura Exportación clear validation. Per-CFE emission time dropped from 12 minutes of manual touch-up to 90 seconds. Deductibility was recovered on 3 prior credit notes DGI had previously rejected. Cost: USD 3,800 in one-time work plus OCA module support (no recurring cost).

The homologación test did not surface anything unexpected — it surfaced everything the partner had deprioritized before the deadline. The difference was sequencing the discovery before the first Brazilian customer was left without an invoice.

Checklist + what's next

To run your own test, I put together a CFE 25-1 checklist for Odoo18 pages47 control points segmented by CFE type, ready-to-use XML templates for homologación, and DGI rejection-message examples with their decoding.

Download it free (email-gated) at data-metrics.pro/checklist-cfe-25-1. If you'd rather delegate, book 30 minutes for an Odoo install audit and we'll walk the six checks together.

CFE 25-1 is not a paint job — it's a new XML schema DGI parses without mercy. The homologación test is the practical way to know, before a buyer calls, that your Odoo is producing a valid document. The gap between a prepared emisor and one that improvises is six checks, half a day of data audit, and the discipline to rerun the test after every upgrade.

For more on how CFE 25-1 fits the Uruguayan stack, see the DGI CFE 25-1 pillarthe Odoo Uruguay implementationthe implementation serviceour Odoo project rescue, or the Odoo audit checklist.

Sergei Filatov / Hacker Sergio — Forbes 30 Under 30 LATAM, Lima. I help LATAM SMBs avoid losing money on bad compliance and unsupervised Odoo installs. About · Portfolio.

Frequently asked questions

Did DGI extend the CFE 25-1 production deadline?

Officially, no — March 3, 2026 stuck as the final date. In the first weeks there was de-facto operational tolerance per Uruguayan partners, but that can end at any moment.

Leaning on the "tolerance" is risky for an operation that already emits hundreds of CFEs per month.

What's the fine for an invalid CFE?

DGI's formal infractions land in the UY$ 4,000–UY$ 36,000 range per incident based on severity. Repeat offenders can have their emisor status suspended, which blocks all emissions until the case is resolved. The exact figure is set by the inspector based on context.

Can I test CFE 25-1 with dummy data?

Yes. Homologación does not require real partners — DGI publishes a list of test RUTs in the e-Factura docs. It's the most comfortable way to cover edge cases without contaminating your production base.

Does Odoo Community 16 support CFE 25-1?

Only with the OCA l10n_uy module from February 2026 or later, plus l10n_uy_export if you handle exports. Without those modules, there is no support. Odoo 17 and 18 Enterprise ship support out of the box if the maintenance contract is active.

How long does the migration to 25-1 take?

SMB with a single B2C till: 1–2 days. B2B importer with multi-currency: about a week. Exporter with VUCE integration: 2–4 weeks. Large companies with custom invoicing: 4–8 weeks.

Do I need a separate DGI contract to use homologación?

No. The homologación environment is available to every registered emisor with the same certificate. All it takes is switching the endpoint in Odoo's configuration and keeping a separate database so tests don't mix with production.

What do I do if DGI rejects a CFE I already issued to a customer?

A rejected CFE has no legal standing — you have to re-emit and re-send the corrected document. Meanwhile the customer can't apply deductibility and you can't close the period. That's why a daily DGI-response review in the first week post-migration is worth scheduling.

Is it enough to run the test once and forget?

No. DGI publishes minor fix packs every 6–8 weeks and OCA partners refresh modules on a similar cadence. A short test after every upgrade beats a long test once a year.