Skip to main content
Version: Latest

9. Onboarding

For the frontend-facing wizard that drives this endpoint (organization profile → address → tenant defaults → VAT → ZATCA Phase 2 → this onboarding call), see Chapter 16 — Tenant Setup Wizard Integration Guide.

9.1 Device (Solution Unit) Onboarding — OTP Flow​

The OTP itself is obtained by the tenant admin directly from ZATCA's own portal, out of band — it arrives at the ERP only as an HTTP header on the POST api/EInvoicing/Onboarding call, never from configuration. A Otp: 123345 value present in appsettings.Development.json/appsettings.production.json's ZatcaPortalSettings section is a leftover fixed testing value, not a live onboarding mechanism — confirmed by the absence of any code path that reads a ZatcaPortalSettings.Otp property (no such property exists on the class at all).

9.2 Onboarding / Certificate Lifecycle Services​

ServiceResponsibility
OnboardingProcessFlowServiceOrchestrates Compliance CSID → Compliance checks → Production CSID, sequentially, for Initialize(type, otp)
OnboardingValidatorServiceTenantIsOnboarded()/CheckOnboardingStatus() — reads FatooraSecretSettings.Onboarded, throws BadRequestException if not onboarded
OnboardingComplianceCsidServiceRequests the Compliance CSID from ZATCA (via ClientCsidService.Compliance)
OnboardingProductionCsidServiceRequests/renews the Production CSID (via ClientCsidService.Production); throws if FatooraSecretSettings.Onboarded == false
OnboardingComplianceCheckServiceRuns the "compliance checks" step (SimplifiedInvoiceCompliance, StandardInvoiceCompliance — the file StandardTaxInvoiceCompliance.cs actually declares a class named StandardInvoiceCompliance, a filename/class-name mismatch)
X509CertificateServiceGenerates the CSR, generates/imports the EC key pair, caches the resulting certificate in the Windows certificate store
ECKeyPairHelperGenerates the EC key pair (SecObjectIdentifiers.SecP256k1)

9.3 Authentication During Onboarding​

The Compliance CSID request (the very first onboarding step) correctly does not attach Basic-Auth — this matches ZATCA's spec, since the caller doesn't have a CSID yet at that point; it authenticates with the CSR and OTP only.

Every step after that — the Production CSID request (both initial issuance and renewal) — does require ZATCA-side Basic-Auth. This is exactly the call path the Phase 0/0.1/0.2 authentication finding and fix covered — see Chapter 7 — Security § 7.2. Before the Phase 0.2 fix, any onboarding attempt that reached the Production CSID step would have received an unauthenticated request rejection from ZATCA.

9.4 Onboarding Events (MediatR)​

All 8 events use MediatR (INotification/INotificationHandler<T>), not the platform's generic Notification Framework:

EventPublished fromHandler action
OnboardingCompletedEventClientCsidServicePersists ProductionCsidSettings/FatooraSecretSettings. Logging only
OnboardingRenewalEventOnboarding.ProcessFlowServiceRemoves the X.509 cert from the certificate store
SwitchToProductionModeEventController, via IMediator.PublishValidates the mode transition, clears/sets app settings
SingleComplianceCheckDoneEventClientComplianceServiceFlips a boolean flag per invoice type in ComplianceChecksSettings
CompilanceChecksFailureEventClientComplianceServiceMarks OTP Invalid = true, clears settings to restart onboarding
OtpIsProvidedEventOnboarding.ProcessFlowServiceValidates OTP format/expiry; throws BadRequestException on failure
OtpIsRejectedEventClientCsidServiceSets Invalid = true in settings
OnboardingStartOverEventOnboarding.ProcessFlowServiceRevokes/removes the X.509 cert; throws if not revoked on the ZATCA portal first

Every handler does only state persistence, certificate-store operations, logging, or throws a validation exception — none call any communication/notification interface. See Chapter 12 — Known Limitations for what this means practically (no alert if onboarding fails or a certificate is about to expire).

9.5 No ERP Workflow Triggers Onboarding​

Onboarding, like invoice submission, is reachable only via its dedicated controller endpoint — no ERP business workflow initiates it automatically. A tenant admin (or whatever caller has the OTP) drives the process manually, one HTTP call at a time.