Home / Blog / Tutorials / GTI Costa Rica
TutorialsCosta Rica

GTI electronic invoicing in Costa Rica with Odoo: 2026 operational guide

How Hacienda validates every receipt in real time with GTI v4.4.
Why a careless l10n_cr setup in Odoo costs days at month-close.

Sergei Filatov
Sergei FilatovFounder · data-metrics.pro · May 26, 2026
◷ 9 min read

What Hacienda requires with GTI 4.4 in 2026

Hacienda Costa Rica requires every taxpayer with for-profit activity to issue cryptographically signed electronic receipts and have them validated against ATV (Administración Tributaria Virtual) before delivering them to the customer. If your Odoo emits a malformed XML or uses an expired signature, Hacienda responds in seconds with a rejection and the transaction does not exist for tax purposes.

Version 4.4 of the GTI schema (Integrated Tax Management) tightened three points compared to 4.3:

  1. Mandatory electronic signature with a certificate issued by SINPE or an authorized certification authority. The certificate expires every 2 years — renewal is a separate process with your issuing bank.
  2. Online pre-validation against ATV. Without a positive response (status aceptado), the receipt has no legal value even if the customer already holds it.
  3. Sequence traceability — the receipt sequence (50 digits) and the numeric key (50 additional digits) must match Hacienda's internal control. Sequence gaps trigger automatic auditing.
!
What changed in 2026

Hacienda started cross-checking receipts against D-101 (income tax) and D-104 (VAT) returns. If you issued an electronic invoice for professional services and didn't report it in the corresponding period, the system flags automatic inconsistency and your D-150 returns with an error. Base penalty is 50% of the omitted tax, regardless of whether it was an oversight or an ERP technical issue.

Mandatory receipt types by operation

The GTI schema defines six types of electronic receipts. Not all apply to every company: it depends on taxpayer type (traditional vs. simplified regime) and operation type. Critical for an SMB running Odoo:

  • Electronic invoice (FE) — sale to a taxpayer with a corporate ID. Generates tax credit rights for the receiver.
  • Electronic ticket (TE) — sale to a final consumer without an ID. No tax credit.
  • Electronic credit note (NCE) — voids or reduces a prior receipt. Mandatory for returns, post-issuance discounts, or corrections.
  • Electronic debit note (NDE) — increases the amount of a prior receipt. Typical for price adjustments.
  • Electronic purchase invoice (FEC) — you issue it when receiving goods/services from a supplier who doesn't invoice electronically (rarer each year).
  • Electronic export invoice (FEE) — for sales abroad. Different XML format with tariff codes.

Common mistake in Odoo: invoicing a foreign customer with FE instead of FEE. Hacienda accepts the XML but the foreign customer can't deduct it, and you lose the trail for VAT exoneration on exports.

Configure l10n_cr step by step

The l10n_cr module ships with Odoo Community and Enterprise. What does not ship is the certified connector to Hacienda — that comes from a third-party module (Vauxoo, OdooGap, ApiThemes). Before choosing one, confirm it supports:

  • XAdES-EPES signing over the GTI 4.4 XML (not 4.3, which Hacienda stopped accepting in February 2025).
  • Async queue with automatic retries when ATV responds with timeout (common at month-close).
  • Automatic ATV session token renewal — it expires every 1 hour.
  • Correct generation of the 50-digit numeric key per Hacienda spec.

#1. Company setup

In Accounting → Configuration → Companies → Your company:

  • Corporate ID with check digit in the correct field. Common error: omitting the hyphen between numeric blocks — Hacienda returns CodigoIdentificacionInvalido.
  • Primary economic activity using the CAECR code (Costa Rica Economic Activity Classification), not the generic CIIU code.
  • Tax regime — Traditional, Simplified, or ZEE (Special Economic Zone). This determines which receipt types you can issue.

#2. Electronic signature certificate

Load the digital signing certificate (P12, with passphrase). It lasts 2 years — renewal is a separate process with your issuing bank or SINPE. Without a valid certificate, Odoo generates the XML but cannot sign it, and ATV rejects with FirmaInvalida.

#3. Taxes and withholdings

Activate Costa Rican taxes from Accounting → Configuration → Taxes. Critical ones:

  • VAT 13%, 4%, 2%, 1%, 0% Exempt (mapped to GTI codes).
  • Income tax withholding for professional services (10% or 15% depending on regime).
  • Selective consumption tax if you sell goods on the MH-2024-001 list.

#4. Branches and headquarters

If you operate multiple branches under one corporate ID, each branch needs its own terminal in ATV. Odoo must be able to assign the branch code when issuing, otherwise every receipt ends up under terminal 00001 and Hacienda can't distinguish points of sale.

Typical issuance errors

Anonymous case: chemical products distributor in GAM, 850 invoices/month. 18% bounced back from ATV. Root causes, in order of frequency:

  1. Duplicate numeric key — the connector reused sequences after a transaction rollback. Result: status RechazadoClaveExiste. Fix: persist the sequence in a dedicated Odoo table with pessimistic locking, don't trust the receipt's own field.
  2. ATV timeout at month-close — Hacienda's backend saturates between the 12th and 15th of each month. Fix: async queue with exponential retries (1s, 3s, 10s, 30s).
  3. Signature with expired certificate — nobody monitored the expiration date. Fix: cron alert 30 days before expiry, sent to a real fiscal recipient, not a generic accounting inbox.
  4. Receiver without valid ID — Odoo allowed saving contacts with malformed IDs. Hacienda validates format before accepting. Fix: regex validation on the res.partner model and block issuance on failure.
  5. Total amount doesn't match line items — 1-colón rounding difference. Hacienda rejects with TotalNoCoincide. Fix: patch the connector to use banker's rounding consistently between lines and total.

After the fix, rejection rate dropped from 18% to 1.1%. The cost of NOT fixing it: 153 invoices/month that went uncollected until manual re-invoicing — approx. ₡21M CRC of unnecessary aged AR every month.

i
Metric worth watching before going live

Typical latency: 2–6 seconds per receipt. If your Odoo doesn't handle async retries, you'll get false negatives at month-close — receipts that operations consider issued but Hacienda never received.

Case: services SMB in Heredia

Tax consulting firm, 14 employees280 receipts/month (mix of FE and TE). Migrated from a proprietary Costa Rican system to Odoo 17 Community with the Vauxoo connector.

«The promise was saving ₡600K/month in licensing. What we found: if you don't automate the daily reconciliation between Odoo and ATV, you spend 3 days at close identifying which receipts are in limbo. That's 24 person-hours of the accountant, which costs more than the license we saved.»

The solution wasn't going back to the proprietary system but building a daily cron that cross-checks the Hacienda report (downloadable from ATV) against receipts issued in Odoo, flagging discrepancies before the accountant arrives at the office. Close time: from 3 days to 4 hours.

When you need a certified partner

Odoo has official partners in Costa Rica (Vauxoo regional, OdooGap, ApiThemes). You don't always need one. Clear signals you do:

  • You operate in more than one regime (Traditional + Simplified, or Traditional + ZEE).
  • You issue more than 1000 receipts/month — async queue and monitoring become critical.
  • You have international operations (FEE) and VAT exonerations.
  • You need integration with Costa Rican banks (BCR, BAC, BN) for payment reconciliation.
  • Your accounting team doesn't want to touch XML or read Hacienda responses.

For an SMB issuing fewer than 500 receipts/month on Traditional regime with no exports, the standard connector plus an internal technical person is usually enough. The 5-day initial audit against Hacienda, yes — recommended before going live.

Frequently asked questions

Is it mandatory to use a certified connector or can I issue directly from Odoo?

Odoo Community/Enterprise doesn't include an ATV connector in its base distribution. You can implement your own module following the Hacienda spec, but in practice nobody does because XAdES-EPES signing, token renewal, and GTI exception handling are months of work. Certified connectors (Vauxoo, OdooGap, ApiThemes) cost ₡150-300K/year but save you that work.

How long does ATV take to respond to a receipt?

Pre-validation: 2–6 seconds under normal conditions. During peaks (month-close, last business day for taxes) it can go to 30–60 seconds. That's why async processing is mandatory in real operation — blocking the user's HTTP thread during issuance is bad practice.

What happens if Hacienda rejects a receipt after I deliver it to the customer?

Legally the receipt doesn't exist, so the operation generates no tax credit rights for the receiver nor expense support. You must issue an electronic credit note that voids the original receipt (even though it was rejected) and reissue with the correction. The customer should discard the original receipt.

How do I configure sequencing in Odoo so it doesn't clash with the numeric key?

The sequence (50 digits: terminal + type + sequence) and the numeric key (50 digits: country + day + ID + branch + terminal + type + sequence + situation + security code) are distinct but related fields. In Odoo configure them in two separate sequences in Accounting → Configuration → Sequences, both with pessimistic locking. The numeric key is generated at signing time, not on document save.

Do I need an electronic signature to issue an electronic ticket (TE)?

Yes. All electronic receipts in Costa Rica require XAdES-EPES signing with a valid certificate. The TE doesn't generate tax credit, but it's still a legally valid receipt — which is why it needs to be signed and accepted by ATV before delivery to the final consumer.

When must I declare Odoo-issued receipts to Hacienda?

D-104 (VAT) is monthly, due on the 15th of the following month. D-101 (income tax) is annual, due on March 15. Your Odoo must be able to export a sales ledger and a purchase ledger from receipts already accepted by ATV, in the format your accountant needs to file the returns. Reconciling Odoo against ATV before filing prevents inconsistency penalties.

Can I issue receipts in colones and dollars from the same Odoo?

Yes, GTI 4.4 supports multiple currencies. The XML must carry the ISO 4217 code (CRC, USD) and the exchange rate of the day of issuance per the rate published by BCCR. Odoo l10n_cr handles this if you activate multi-currency on the company and configure the daily rate via a cron job against the BCCR endpoint.