Egypt ETA E-Invoice & E-Receipt
The ECOSIRE Egypt ETA module is a country pack that connects Odoo to the Egyptian Tax Authority (ETA) e-invoicing system. Egypt uses a direct government API model: your Odoo instance calls the ETA REST API itself, with no Peppol relay and no third-party service provider. It signs in with OAuth2 client_credentials to get a short-lived token, then submits JSON documents asynchronously.
The module sits on top of the GCC E-Invoicing | Core Engine and adds the Egypt-specific parts: the ETA submission lifecycle (draft → built → submitted → cleared / rejected), submission UUID and document UUID tracking, cancel/reject within the ETA time window, automatic retry of temporary failures, a per-call audit log, and a preprod-first onboarding flow.
| Technical name | ecosire_einvoice_eg |
| Current shipped version | 17.0 → 17.0.1.0.4, 18.0 → 18.0.1.0.4, 19.0 → 19.0.1.0.3 |
| Compatibility | Odoo 17 / 18 / 19 (Community or Enterprise) |
| Price | USD 599 (one-time) — requires GCC E-Invoicing Core (ecosire_einvoice_core) installed alongside |
| Licence | OPL-1 (Odoo Proprietary License v1.0) |
| Category | Accounting / Localizations / EDI |
| ETA authority | Egyptian Tax Authority — sdk.invoicing.eta.gov.eg |
The GCC E-Invoicing suite is live at zatca.demo.ecosire.com — log in with admin / admin. The KSA pack is active on the demo; configuring the Egypt pack needs your own ETA preprod sandbox credentials.
What's new
19.0.1.0.3 · 18.0.1.0.4 · 17.0.1.0.4 (2026-09-17)
- Installs on its own. The package no longer needs a separate ECOSIRE licence module and there is no activation key. Earlier downloads could fail to install on a fresh Odoo because they asked for a companion module that was not part of the package; that no longer happens.
- A guard test now checks on every build that the package is self-contained.
18.0.1.0.3 · 17.0.1.0.3 (2026-09-05)
- The price is now USD 599 on every channel (ecosire.com and the Odoo Apps Store show the same number).
Overview
Egypt's ETA mandate covers B2B e-invoicing (Invoice, Credit Note, Debit Note, and their Export variants) and B2C e-receipt (POS). It has rolled out in phases: large taxpayers first, then mid-size, then small taxpayers and B2C e-receipt. Check the ETA portal to confirm your own filing obligation.
What this module does:
- OAuth2 token management — gets a Bearer token from the ETA Identity Service (
id.eta.gov.eg/id.preprod.eta.gov.eg) and caches it for its 60-minute lifetime, so a new token is not requested on every call. - Document builder — assembles a JSON document skeleton from a posted Odoo invoice (
account.move): issuer TIN/RIN, receiver identity, document type and version, line items with item codes and unit types, tax breakdown, and totals. - Async submission — posts the document to
POST /api/v1.0/documentsubmissions(HTTP 202 means accepted for processing, not yet cleared). The module stores the ETAsubmissionUUIDand, once assigned, thedocumentUUID(26 characters) andlongId(42 characters, used for ETA PDF retrieval). - Submission lifecycle — seven states:
draft → built → submitted → cleared / rejected / pending_retry / dead_letter. Every state change is logged in the record's chatter. - Cancel / reject within the ETA window —
PUT /api/v1.0/documents/state/{UUID}/statefor the issuer (cancel) and the recipient (reject), within the time window ETA allows. - Poll submission status —
GET /api/v1.0/documentsubmissions/{submissionUUID}to reconcile the state after the asynchronous 202. - Automatic retry — a scheduled action every 15 minutes retries submissions in
Pending Retry(temporary 429/503 failures). After five failed attempts a submission moves toDead Letterfor manual review. - Audit log (
eta.audit.log) — every API attempt is recorded with HTTP method, target URL, environment, outcome, ETA error code, and a shortened response excerpt. Secrets are never written to it. - Per-company credentials — credentials live on the company record, so each company in a multi-company database is configured on its own.
- Environment switch — preprod sandbox or production, per company.
- Additional ETA API calls in the connector — document type and version-schema retrieval, recent documents, document details, taxpayer notifications, and EGS/GS1 code registration and search are implemented in the module's ETA client. This release has no dedicated screen for them; they are available to your implementer for automation and diagnostics.
Sandbox-gated areas: ETA publishes the exact JSON document schema (field names, casing, required sub-objects) only through the preprod sandbox Get Document Type Version endpoint. The X.509 eSeal signing algorithm and CanonicalJSON rules live in the ETA integration toolkit (Docker/NuGet/CLI), not in public documentation, and the e-receipt submission endpoint path was not available on the SDK portal when the API contract was verified. These three areas stop with a clear message asking you to complete preprod sandbox onboarding first. Only API paths confirmed against the ETA documentation are implemented.
Requirements
| Requirement | Detail |
|---|---|
| Odoo | 17.0, 18.0, or 19.0 (Community or Enterprise) |
| Required module | ecosire_einvoice_core (GCC E-Invoicing Core Engine) |
| Python packages | requests |
| ETA preprod credentials | OAuth2 client_id + client_secret from the ETA preprod portal — needed before any submission |
| X.509 eSeal certificate | USB hardware token or HSM from an ETA-accredited certification authority — needed for production submissions |
No ECOSIRE licence module and no activation key are needed.
Installation
- Download ECOSIRE GCC E-Invoicing Core and ECOSIRE Egypt ETA E-Invoice from your purchase (Odoo Apps Store or your ecosire.com account).
- Extract both into your Odoo addons directory:
unzip ecosire-einvoice-core-*.zip -d /opt/odoo/addons/unzip ecosire-einvoice-eg-*.zip -d /opt/odoo/addons/
- Install the Python dependency:
pip install requests
- Restart the Odoo service:
sudo systemctl restart odoo
- In Odoo, go to Apps and click Update Apps List.
- Search for ECOSIRE E-Invoicing | Egypt ETA and click Install. The core engine installs automatically as a dependency.
After installation an Egypt (ETA) menu appears under the E-Invoicing app, with ETA Submissions and ETA Audit Log.
Configuration & Credentials
Step 1: Obtain ETA credentials from the preprod portal
Before configuring Odoo, complete taxpayer-system registration on the ETA preprod portal:
- Go to profile.preprod.eta.gov.eg and register your organisation.
- In the taxpayer-system registration section, create a new system integration and note the Client ID and Client Secret.
- Install the ETA Root CA certificate on your development machine (preprod only — never install the preprod certificate on production systems). Admin rights are needed on Windows.
- Download the ETA Postman collection and environment files from the SDK portal FAQ page to check your credentials manually before entering them in Odoo.
- Note your Taxpayer Registration/Identification Number (RIN/TIN) — it is the issuer identity on every document.
- Get an X.509 eSeal certificate from an ETA-accredited certification authority (USB token or HSM) before signing live production documents. Preprod uses document version v0.9, which has signature validation switched off for testing.
Step 2: Enter the credentials in Odoo
- Go to Settings → Companies and open your company.
- Find the Egypt ETA E-Invoicing section added by this module.
- Fill in these fields:
| Field | Where it comes from |
|---|---|
ETA Environment | Choose Preprod Sandbox first; switch to Production only after successful sandbox tests |
ETA Client ID | OAuth2 client_id from the ETA portal system registration |
ETA Client Secret | OAuth2 client_secret from the ETA portal system registration — shown masked |
ETA Registration Number (RIN/TIN) | Your taxpayer registration/identification number |
On-Behalf-Of (Intermediary) | Leave empty for direct submission; set it to the taxpayer RIN only when this ERP submits on behalf of another registered entity |
ETA Document Version | v1.0 for production (signature validation on); v0.9 for transition/testing only (signature validation off) |
- Save. In a multi-company setup, configure each company separately.
Step 3: Check the connection (preprod)
Go to E-Invoicing → Egypt (ETA) → ETA Submissions and click New. Select a posted invoice, set Document Type to Invoice, and click Build Document. If the company RIN is set, the document JSON is assembled and the state moves to Built. Review it on the Document JSON tab — this is the contract-shaped skeleton. Full schema conformance and eSeal signing need the preprod sandbox integration toolkit (see the ETA SDK portal at sdk.invoicing.eta.gov.eg).
Sandbox vs production
| Item | Preprod Sandbox | Production |
|---|---|---|
| Identity service | id.preprod.eta.gov.eg | id.eta.gov.eg |
| API base URL | api.preprod.invoicing.eta.gov.eg | api.invoicing.eta.gov.eg |
| Root CA | Install ETA preprod Root CA (dev machine only) | Standard trusted CA |
| Document version | v0.9 (signature validation off) | v1.0 (signature required) |
| Signing | Not required (v0.9) | X.509 eSeal certificate required |
Switch the company's ETA Environment to Production only after you have validated the full flow — schema-exact document assembly and eSeal signing — in the preprod sandbox.
Usage
The submission workflow
Each ETA document is an ETA Submission record linked to an Odoo invoice:
- Create a submission — E-Invoicing → Egypt (ETA) → ETA Submissions → New. Select the posted invoice and the document type (Invoice, Credit Note, Debit Note, Export Invoice, Export Credit Note, or Export Debit Note).
- Build Document — assembles the JSON payload from the invoice (issuer, receiver, lines, taxes, totals). State moves to
Built. - Submit to ETA — posts the payload to
POST /api/v1.0/documentsubmissions. ETA answers HTTP 202 with asubmissionUUID. State moves toSubmitted. - Poll Status — queries
GET /api/v1.0/documentsubmissions/{submissionUUID}. When ETA has processed the document, the state moves toCleared(valid) orRejected. - Cancel at ETA / Reject at ETA — within the ETA time window, the issuer can cancel and the recipient can reject. After the window closes, issue a credit note instead.
The list view has filters for Draft, Submitted, Cleared, Rejected and Pending Retry, and groupings by state, document type and environment.
Submission states
| State | Meaning |
|---|---|
| Draft | Record created; no document built yet |
| Built | JSON document assembled; not yet submitted |
| Submitted | Accepted by ETA (HTTP 202); awaiting processing |
| Cleared | ETA confirmed the document is valid |
| Rejected | ETA rejected the document (see the audit log for the error code) |
| Pending Retry | Temporary failure (429/503) — the retry scheduled action tries again |
| Dead Letter | Five failed attempts — manual review needed |
Automatic retry
The scheduled action ETA: Retry Pending Submissions runs every 15 minutes (adjustable in Settings → Technical → Automation → Scheduled Actions) and retries every submission in Pending Retry. After five failed attempts the submission moves to Dead Letter.
Audit log
E-Invoicing → Egypt (ETA) → ETA Audit Log lists every API call: HTTP method, target URL, environment (preprod/production), outcome, ETA error code, and a shortened response excerpt. Each submission also shows its own entries on its Audit Log tab. Credentials are never written to the log.
Troubleshooting / FAQ
| Issue | Cause and fix |
|---|---|
| "ETA credentials missing" | The company's ETA Client ID or Client Secret is empty. Open the company under Settings → Companies and fill both fields in the Egypt ETA E-Invoicing section. |
| "Set ETA Registration Number before building" | The company RIN/TIN is empty. Set ETA Registration Number (RIN/TIN) on the company. |
| Install fails because a required companion module is "not available in your system" | You have a download older than 19.0.1.0.3 / 18.0.1.0.4 / 17.0.1.0.4. Download the current build; it installs on its own. |
| HTTP 400 BadStructure | The payload does not match the ETA JSON schema yet. Complete schema-exact assembly with the ETA integration toolkit and check the JSON against the schema from the sandbox Get Document Type Version endpoint. |
| HTTP 400 MaximumSizeExceeded | The submission is too large. Split it into smaller batches. |
| HTTP 403 IncorrectSubmitter | The client_id does not belong to the issuer TIN. Confirm the credentials come from the same taxpayer-system registration as the company RIN. |
| HTTP 422 DuplicateSubmission | An identical document was submitted in the last 10 minutes. Wait and check whether the first one was accepted. |
| HTTP 429 / submission in Pending Retry | Rate limit reached. The retry scheduled action handles it. |
| HTTP 503 / submission in Pending Retry | ETA is overloaded. The retry scheduled action handles it. |
| "X.509 eSeal signing algorithm — sandbox required" | Document signing is gated. Complete ETA preprod sandbox onboarding with the ETA integration toolkit (Docker/NuGet/CLI). |
| "eReceipt endpoint path is not verified" | The e-receipt submission path was not available on the SDK portal when the contract was verified. Get the confirmed path through preprod sandbox access before using e-receipt submission. |
| State stays at Submitted | ETA processes documents asynchronously. Click Poll Status a few minutes after submitting, or check the document on the ETA invoicing portal (invoicing.eta.gov.eg). |
| Rejection after the time window | Cancellation is no longer possible. Issue a credit note in Odoo and submit it as a Credit Note document. |
| Preprod SSL errors | The ETA preprod Root CA is not installed. Follow sdk.invoicing.eta.gov.eg/faq/ (admin rights needed on Windows). Never install the preprod certificate on production machines. |
Why does the built document say production_ready: false?
The builder produces a skeleton whose top-level shape follows the ETA contract (issuer, receiver, type, lines, totals). The schema-exact field names and the eSeal signature are added through the ETA integration toolkit during preprod. The _ecosire_meta.production_ready: false flag in the JSON marks the skeleton as ready for review but not yet signed for live submission.
Can I use this module without GCC E-Invoicing Core?
No. ecosire_einvoice_core is a required dependency.
Does this module support e-receipt (B2C POS)?
Not yet in production. The e-receipt submission paths were not available on the ETA SDK portal when the API contract was verified (June 2026), so that path stops with a clear message. B2B e-invoicing documents are fully wired.
Which ETA document version should I use?
v1.0 is the production version (signature validation on). v0.9 has signature validation off and is for transition and testing only.
Support
- Related module: GCC E-Invoicing | Core Engine
- ETA developer portal: sdk.invoicing.eta.gov.eg
- ETA taxpayer portal (production): profile.eta.gov.eg
- ETA taxpayer portal (preprod): profile.preprod.eta.gov.eg
- General Troubleshooting
- Email: info@ecosire.com
- Support Portal