EtaInvoice.Net 1.0.1

dotnet add package EtaInvoice.Net --version 1.0.1
                    
NuGet\Install-Package EtaInvoice.Net -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="EtaInvoice.Net" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="EtaInvoice.Net" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="EtaInvoice.Net" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add EtaInvoice.Net --version 1.0.1
                    
#r "nuget: EtaInvoice.Net, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package EtaInvoice.Net@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=EtaInvoice.Net&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=EtaInvoice.Net&version=1.0.1
                    
Install as a Cake Tool

EtaInvoice.Net

License: MIT .NET CI GitHub stars

EtaInvoice.Net

A clean, modern .NET SDK for the Egyptian Tax Authority (ETA) e-invoicing APIs — submit signed e-invoices, track their validation status, cancel/reject documents, and search your document history.

Disclaimer: community SDK, not affiliated with or endorsed by the Egyptian Tax Authority. API shapes follow the official ETA SDK documentation. Always verify against the official docs before production use.

Install

dotnet add package EtaInvoice

Targets netstandard2.0 and net8.0. Only dependency: System.Text.Json (+ DI abstractions).

Quickstart

using EtaInvoice;
using EtaInvoice.Models;

var client = new EtaClient(new EtaClientOptions
{
    ClientId = "<your-client-id>",       // from the ETA portal (register your ERP)
    ClientSecret = "<your-client-secret>",
    // BaseUrl/AuthUrl default to the preprod environment
});

var document = new EtaDocument
{
    Issuer = new Taxpayer
    {
        Type = TaxpayerTypes.Business,
        Id = "123456789",                 // tax registration number
        Name = "My Company",
        Address = new TaxpayerAddress
        {
            BranchId = "0",
            Country = "EG",
            Governate = "Cairo",
            RegionCity = "Nasr City",
            Street = "Main St",
            BuildingNumber = "10"
        }
    },
    Receiver = new Taxpayer
    {
        Type = TaxpayerTypes.Business,
        Id = "987654321",
        Name = "Buyer Co",
        Address = new TaxpayerAddress
        {
            Country = "EG", Governate = "Giza", RegionCity = "Dokki",
            Street = "Side St", BuildingNumber = "5"
        }
    },
    DocumentType = DocumentTypes.Invoice, // "i"
    DocumentTypeVersion = "1.0",
    DateTimeIssued = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssZ"),
    TaxpayerActivityCode = "1234",
    InternalId = "INV-2026-0001",
    InvoiceLines = new List<InvoiceLine>
    {
        new InvoiceLine
        {
            Description = "Consulting service",
            ItemType = "EGS",
            ItemCode = "EG-1234",
            UnitType = "EA",
            Quantity = 1,
            UnitValue = new UnitValue { CurrencySold = "EGP", AmountEGP = 1000m },
            SalesTotal = 1000m,
            Total = 1140m,
            TaxableItems = new List<TaxableItem>
            {
                new TaxableItem { TaxType = "T1", SubType = "V009", Amount = 140m, Rate = 14m }
            }
        }
    },
    TotalSalesAmount = 1000m,
    NetAmount = 1000m,
    TaxTotals = new List<TaxTotal> { new TaxTotal { TaxType = "T1", Amount = 140m } },
    TotalAmount = 1140m
};

// Optional: catch structural mistakes before the network call.
var problems = EtaInvoice.Validation.EtaDocumentValidator.Validate(document);

// Submit. Pass an IDocumentSigner to attach a CAdES-BES issuer signature
// (required in production — see "Signing" below).
var result = await client.SubmitDocumentsAsync(new[] { document }, signer: mySigner);

Console.WriteLine(result.SubmissionUuid);
foreach (var accepted in result.AcceptedDocuments)
    Console.WriteLine($"accepted: {accepted.InternalId} -> {accepted.Uuid}");
foreach (var rejected in result.RejectedDocuments)
    Console.WriteLine($"rejected: {rejected.InternalId}: {rejected.Error.Code}");

ASP.NET Core DI

services.AddEtaInvoice(options =>
{
    options.ClientId = builder.Configuration["Eta:ClientId"];
    options.ClientSecret = builder.Configuration["Eta:ClientSecret"];
});

// then inject EtaClient anywhere

API reference

All methods target the /api/v1.0/… endpoints documented in the official ETA SDK.

Method Endpoint
GetAccessTokenAsync() OAuth2 client-credentials (/connect/token, scope InvoicingAPI); token cached until expiry
SubmitDocumentsAsync(documents, signer?) POST /api/v1.0/documentsubmissions/ → 202 {submissionUUID, acceptedDocuments, rejectedDocuments}
GetSubmissionAsync(uuid, pageNo?, pageSize?) GET /api/v1.0/documentsubmissions/{uuid}
GetDocumentDetailsAsync(uuid) GET /api/v1.0/documents/{uuid}/details (status + validation results)
GetDocumentRawAsync(uuid) GET /api/v1.0/documents/{uuid}/raw (source JSON + ETA metadata)
GetDocumentPdfAsync(uuid) GET /api/v1.0/documents/{uuid}/pdf → byte[]
CancelDocumentAsync(uuid, reason) PUT /api/v1.0/documents/state/{uuid}/state (cancelled)
RejectDocumentAsync(uuid, reason) PUT /api/v1.0/documents/state/{uuid}/state (rejected)
DeclineCancellationAsync(uuid) PUT /api/v1.0/documents/state/{uuid}/decline/cancelation
SearchDocumentsAsync(query) GET /api/v1.0/documents/search (paged via metadata.continuationToken)

Document types: DocumentTypes.Invoice (i), CreditNote (c), DebitNote (d), ImportInvoice (ii), ExportInvoice (ei), ExportCreditNote (ec), ExportDebitNote (ed).

Errors surface as EtaApiException with StatusCode, ErrorCode (e.g. DuplicateSubmission, IncorrectSubmitter) and the raw response body.

Signing — read this before production

Real ETA signing requires your eSeal certificate (USB token / HSM / key vault) producing a CAdES-BES signature over the canonical document JSON. Private key material must never leave your infrastructure, so this SDK ships no built-in signer — instead:

  1. Implement IDocumentSigner with your signing service (USB token middleware, HSM, cloud vault).
  2. Pass it to SubmitDocumentsAsync(documents, signer) — the SDK canonicalizes each document (deterministic JSON: sorted keys, no whitespace, signatures section excluded, per ETA's "signed content is the entire document except the signature section" rule) and embeds the returned Base64 value as the issuer (I) signature.
  3. Verify the canonical string against the official ETA "Signature Creation" documentation (or the official EInvoicingSigner tracing tool) before going live — canonicalization details are defined by ETA.

Submitting without a signer is fine for preprod experimentation; production ETA rejects unsigned B2B documents.

Preprod vs production

Defaults point at preprod (api.preprod.invoicing.eta.gov.eg, id.preprod.eta.gov.eg). For production use EtaClientOptions.Production(clientId, clientSecret).

Scope & honesty

  • ✅ Verified against the official ETA SDK docs (Oct 2026): auth, submit, submission status, document details/raw/PDF, cancel, reject, decline-cancellation, search.
  • ⚠️ IDocumentSigner is an interface — you bring the real CAdES-BES signing (USB token/HSM). No fake crypto anywhere.
  • ⚠️ Client-side validation (EtaDocumentValidator) catches structural mistakes only; ETA server-side validation is authoritative.
  • Not covered (yet): EGS/GS1 code management APIs, document packages, notification callbacks, e-receipt (POS) APIs. Issues and PRs welcome.

License

MIT — see LICENSE.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 50 10/8/2026
1.0.0 45 10/8/2026

NuGet polish release: branded package icon, embedded README, and full repository metadata.