Skip to content

Integration Service — ZATCA E-Invoicing

The Integration service implements Saudi Arabia's mandatory e-invoicing requirements as defined by ZATCA (Zakat, Tax and Customs Authority — هيئة الزكاة والضريبة والجمارك).


Overview

PropertyValue
ServiceIntegration.Apis
CAE placementPrivate CAE
SourcePlatforms/Src/InfrastructureServices/Integration/
NuGet packagesMicrotec.Zatca.Integration, Microtec.Zatca.Infrastructure
Regulatory bodyZATCA (Saudi Arabia)
StandardUBL 2.1 XML, CSID certificates

What is ZATCA?

ZATCA is the Saudi government authority responsible for tax collection and customs. As part of Vision 2030, ZATCA mandated a phased e-invoicing (Fatoorah / فاتورة) programme:

PhaseScopeEffective
Phase 1 — GenerationTaxpayers must generate and store structured electronic invoices (offline)December 2021
Phase 2 — IntegrationInvoices must be cryptographically signed and submitted to ZATCA in real timeRolled out from January 2023 by taxpayer tier

Microtec ERP supports both phases.


Architecture

The Integration service acts as the dedicated ZATCA adapter. The ERP sales module calls it via the internal public API client (IIntegrationPublicApi) rather than calling ZATCA directly.


NuGet Packages

PackageResponsibility
Microtec.Zatca.IntegrationZATCA HTTP client, request/response models, UBL XML builders
Microtec.Zatca.InfrastructureCertificate management, cryptographic signing, storage adapters

Both packages are published to the private Azure DevOps NuGet feed.


IZatcaService Interface

csharp
public interface IZatcaService
{
    /// <summary>
    /// Onboard a new device (cryptographic unit) with ZATCA.
    /// Returns the Compliance CSID (CCSID).
    /// </summary>
    Task<OnboardingResult> OnboardDeviceAsync(
        OnboardingRequest request,
        CancellationToken ct = default);

    /// <summary>
    /// Submit an invoice for clearance (B2B, > SAR 1,000).
    /// ZATCA validates and returns a cleared UUID.
    /// </summary>
    Task<ClearanceResult> ClearInvoiceAsync(
        ZatcaInvoice invoice,
        CancellationToken ct = default);

    /// <summary>
    /// Report an invoice to ZATCA (B2C, simplified invoices).
    /// Does not require prior clearance.
    /// </summary>
    Task<ReportingResult> ReportInvoiceAsync(
        ZatcaInvoice invoice,
        CancellationToken ct = default);

    /// <summary>
    /// Check the compliance status of an existing CSID.
    /// </summary>
    Task<ComplianceStatus> CheckComplianceAsync(
        string csid,
        CancellationToken ct = default);
}

Device Onboarding Flow

Before submitting invoices, each tenant must register a cryptographic stamp identity (CSID) with ZATCA:

The OTP is a one-time password obtained by the tenant admin from the ZATCA Fatoorah portal.


Invoice Submission Flow

Phase 2 — Clearance (B2B invoices above SAR 1,000)

Phase 2 — Reporting (B2C simplified invoices)

Same flow as clearance, but uses the /invoices/reporting ZATCA endpoint instead. No real-time validation response — ZATCA batch-validates reported invoices asynchronously.


Invoice Statuses

StatusMeaning
DraftInvoice created in ERP but not yet submitted
PendingSubmitted to ZATCA, awaiting response
ClearedZATCA confirmed clearance (B2B)
ReportedZATCA confirmed receipt (B2C simplified)
RejectedZATCA returned validation errors
ErrorSubmission failed (network, certificate, or system error)

Configuration

json
// appsettings.json (Integration.Apis)
{
  "Zatca": {
    "BaseUrl": "https://gw-fatoorah.zatca.gov.sa/e-invoicing/developer-portal",
    "Environment": "Sandbox",
    "ApiVersion": "V2"
  }
}
KeyValuesDescription
Zatca:EnvironmentSandbox, ProductionSelects ZATCA endpoint
Zatca:BaseUrlURLOverride the base URL (used for sandbox/staging)
Zatca:ApiVersionV2ZATCA API version

Sandbox vs Production

Always use Sandbox in dev/stage environments. Production CSIDs are tied to the tenant's ZATCA account and will be revoked if misused.


Error Handling

ZATCA returns structured XML validation errors. These are mapped to the standard ApiResponse envelope:

json
{
  "success": false,
  "messageCode": 3006,
  "message": "ZATCA validation failed: [BT-5] Invoice date cannot be in the future",
  "data": {
    "zatcaErrors": [
      { "code": "BT-5", "message": "Invoice date cannot be in the future" }
    ]
  }
}

Common ZATCA error categories:

ZATCA Error CategoryTypical Cause
BT-*Invoice field validation (amount, date, VAT number)
BG-*Invoice group validation (missing sections)
CertificateExpiredPCSID has expired — re-onboard required
DuplicateInvoiceSame invoice UUID submitted twice

  • ZATCA Fatoorah developer portal: https://zatca.gov.sa/en/E-Invoicing
  • UBL 2.1 specification used by ZATCA: https://docs.oasis-open.org/ubl/os-UBL-2.1/
  • Internal service: Platforms/Src/InfrastructureServices/Integration/
  • NuGet source: Platforms/Src/InfrastructureServices/Zatca/

Internal Documentation — Microtec Platform Team