Condividi tramite


Onboarding della fatturazione elettronica in Arabia Saudita

L'onboarding è obbligatorio per tutti i contribuenti soggetti a fatturazione elettronica in Arabia Saudita. Grazie al processo di onboarding, i contribuenti ottengono i codici identificativi crittografici (CSID). I CSID sono necessari per l'integrazione con il portale fatturazione elettronica gestito dall'autorità fiscale dell'Arabia Saudita (ZATCA) e per l'ulteriore invio di fatture elettroniche.

Questo articolo spiega come integrare i contribuenti e il loro software fatturazione elettronica con le autorità fiscali dell'Arabia Saudita.

Prerequisiti

  • La persona giuridica deve essere registrata come contribuente in Arabia Saudita e deve avere un numero di registrazione IVA valido.
  • La persona giuridica deve avere accesso al Portale fiscale dell'Arabia Saudita (ERAD) .

Processo di onboarding

Il processo di onboarding si compone di due fasi:

  1. Ottenere un CSID di conformità (CCSID), che ZATCA assegna per eseguire controlli di conformità delle soluzioni di generazione di fatture elettroniche (EGS).
  2. Ottenere un CSID di produzione (PCSID), che ZATCA assegna agli EGS conformi.

Flusso di lavoro di onboarding.

Ottieni un CCSID

  1. Nel Portale fiscale dell'Arabia Saudita (ERAD), accedi al Portale di onboarding e gestione selezionando il riquadro pertinente.

  2. Nella pagina di destinazione principale del portale di onboarding e gestione, Seleziona il riquadro Nuova unità/dispositivo di soluzione di onboarding , quindi Seleziona Genera il codice OTP. Il codice OTP è valido solo per un'ora dopo la sua generazione. Assicurati di utilizzarlo entro quel lasso di tempo frame.

  3. Seleziona il numero di codici password monouso (OTP) da generare. Il numero dipende dal numero di unità di generazione della fatturazione elettronica (dispositivi) che verranno utilizzate.

  4. Salva i codici OTP generati in modo da poterli utilizzare in passaggi successivi.

  5. Preparare un file di configurazione per la richiesta di firma del certificato. Questo file di configurazione dovrebbe essere sotto forma di file di testo normale contenente i seguenti dati.

    oid_section = OIDs
    [OIDs]
    certificateTemplateName = 1.3.6.1.4.1.311.20.2
    [req]
    default_bits = 2048
    emailAddress = MyEmail@email.com
    req_extensions = v3_req
    x509_extensions = v3_ca
    prompt = no
    default_md = sha 256
    req_extensions = req_ext
    distinguished_name = dn
    [dn]
    C=SA
    OU=Riyad Branch
    O=Contoso
    CN=EA123456789
    [v3_req]
    basicConstraints = CA:FALSE
    keyUsage = digitalSignature, nonRepudiation, keyEncipherment
    [req_ext]
    certificateTemplateName = ASN1:PRINTABLESTRING:ZATCA-Code-Signing
    subjectAltName = dirName:alt_names
    [alt_names]
    SN=1-TST|2-TST|3-ed22f1d8-e6a2-1118-9b58-d9a8f11e445f
    UID=310122393500003
    title=1100
    registeredAddress= MyAddress
    businessCategory=Industry
    
  6. Salvare il file nella stessa posizione dello script di onboarding con il nome csr_config.txt.

  7. Nel file di configurazione, aggiornare il valore emailAddress e i seguenti dati specifici.

    Codice Description Specifica
    Z Il codice paese/regione. Un codice di due lettere (ISO 3166 Alpha-2)
    UO Il nome dell'unità organizzativa. Per i contribuenti normali il valore è testo libero. Per i gruppi IVA, identificare il valore tramite l'undicesima cifra dell'identificativo dell'organizzazione, ovvero "1". Verificare che il dato inserito sia un codice identificativo fiscale (TIN) di 10 cifre.
    O Il nome dell'organizzazione o del contribuente. Testo libero
    CN Nome univoco della soluzione o dell'unità. Testo libero
    SN Codice identificativo univoco della soluzione. Testo libero
    UID Il numero di partita IVA del contribuente. Quindici cifre. Questo numero inizia con "3" e finisce con "3".
    titolo Tipo di documento che verrà emesso dall'unità di soluzione del contribuente. Input numerico a quattro cifre che utilizza "0" e "1" mappati su "TSCZ": 0 = Falso/Non supportato, 1 = Vero/Supportato. T = Fattura fiscale (standard), S = Fattura fiscale semplificata, C = Per uso futuro, Z = Per uso futuro.
    Indirizzo registrato L'indirizzo della filiale o della sede in cui è ubicato principalmente il dispositivo o l'unità di soluzione. Testo libero
    Categoria aziendale Il settore o l'industria per cui il dispositivo o la soluzione genererà fatture. Testo libero

    Nota

    I valori per CN e certificateTemplateName nel file di configurazione sono diversi quando si utilizza il portale di simulazione.

    Nel portale di simulazione:

    • CN - PREZATCA-Firma del codice
    • certificateTemplateName - ASN1:PRINTABLESTRING:PREZATCA-Code-Signing

    In tutti gli altri casi, utilizzare i valori come indicato sopra.

  8. Eseguire lo script di onboarding fornito più avanti in questo articolo. Specificare l'OTP e il file di configurazione come parametri di input. Ecco un esempio: lo script ha due possibili endpoint simulation e prod.

    .\OnboardingScript.ps1 -action getComplianceCSID -endpoint prod -otp 123345 -csrconfig .\csr_config.txt -password 123

    Nota

    Il parametro password è facoltativo e può essere omesso. Se è inclusa, il certificato generato avrà la password specificata.

  9. Il CCSID viene ricevuto come file di certificato "CCSID.pfx" e il segreto del CCSID viene salvato come file txt "CCSIDSecret.txt". Salvare questo file del certificato CCSID nel certificato del Microsoft Azure key vault e salvare il segreto nel Microsoft Azure key vault secret. Per ulteriori informazioni, vedere Certificati e segreti dei clienti.

  10. Configurare la configurazione della funzionalità correlata nella funzionalità Controllo di conformità ZATCA dell'Arabia Saudita (SA) fatturazione elettronica e fare riferimento al certificato CCSID salvato nel key vault. Il certificato verrà utilizzato per la comunicazione con il portale ZATCA fatturazione elettronica.

Controllo di conformità

Dopo aver ottenuto il CSID di conformità tramite lo script PowerShell, ZATCA richiede di completare determinati controlli di conformità inviando fatture campione. Questo passaggio è un prerequisito per richiedere un CSID di produzione.

Assicurarsi che tutti i tipi di fatture campione configurate nel file di configurazione della richiesta di firma del certificato (CSR) vengano inviate correttamente a ZATCA. Utilizzare la procedura standard per l'emissione delle fatture elettroniche. Per maggiori dettagli, vedere Emettere fatture elettroniche in Finanza e Gestione catena di approvvigionamento.

Utilizzare la funzione, "Controllo di conformità ZATCA dell'Arabia Saudita (SA)" in RCS e seguire il Sezione di configurazione specifica per paese/regione passaggi utilizzando il CSID di conformità ottenuto.

Una volta completati con successo i controlli di conformità, utilizzare lo script PowerShell per ottenere il CSID di produzione (fare riferimento allo script di onboarding).

Nota

Nel Titolo campo, se il tipo di documento del file di configurazione è impostato su 1000, per il controllo di conformità devono essere presentate tre fatture campione:

  • Fattura fiscale standard
  • Nota di debito standard
  • Nota di credito standard

Nel Titolo campo, se il tipo di documento del file di configurazione è impostato su 0100, per il controllo di conformità devono essere presentate tre fatture campione:

  • Fattura fiscale semplificata
  • Nota di debito semplificata
  • Nota di credito semplificata

Se il tipo di documento è impostato su 1100, tutte e sei le fatture campione devono essere presentate per il controllo di conformità.

Ottieni un PCSID

Per ottenere un PCSID, è necessario configurare correttamente la soluzione per la generazione e l'invio di fatture elettroniche e la soluzione deve essere pienamente funzionante. Per ottenere questo risultato è necessario completare tutti i passaggi di configurazione preliminare richiesti. Per ulteriori informazioni, vedere Introduzione a fatturazione elettronica per l'Arabia Saudita.

  1. Assicurarsi che tutte le fatture elettroniche vengano inviate correttamente a ZATCA.

  2. Eseguire lo script di onboarding fornito più avanti in questo articolo. Specificare il CCSID come parametro di input. Ecco un esempio: lo script ha due possibili endpoint simulation & prod

    .\OnboardingScript.ps1 -action getProductionCSID -endpoint prod -password 123

    Nota

    Il parametro password è facoltativo e può essere omesso. Se è inclusa, il certificato generato avrà la password specificata.

  3. Il PCSID viene ricevuto come file di certificato in formato PFX. Salvare questo certificato PCSID e il file segreto nel key vault Azure.

  4. Configurare la configurazione delle funzionalità correlate nella funzionalità Invio Zatca saudita (SA) fatturazione elettronica. Includere il certificato PCSID e il segreto nei parametri del key vault in RCS.

Dopo aver completato tutti i passaggi di configurazione, il sistema è pronto per essere utilizzato in modalità di produzione.

Per rivedere i CSID ottenuti sul lato ZATCA, utilizzare il riquadro Rivedi l'identificativo del timbro crittografico (CSID) esistente nella landing page del portale di onboarding e gestione. Questo portale è accessibile dal Portale fiscale saudita (ERAD) principale.

Script di onboarding

Nota

Gli script di esempio non sono supportati da alcun programma o servizio di supporto standard Microsoft. Gli script di esempio vengono forniti COSÌ COME SONO, senza alcuna garanzia. Microsoft declina inoltre ogni garanzia implicita, incluse, senza limitazioni, le garanzie implicite di commerciabilità o di idoneità per uno scopo particolare. L'intero rischio derivante dall'uso o dall'esecuzione degli script di esempio e della documentazione rimane a tuo carico. In nessun caso Microsoft, i suoi autori o chiunque altro coinvolto nella creazione, produzione o distribuzione degli script saranno ritenuti responsabili per eventuali danni (inclusi, senza limitazioni, danni per perdita di profitti aziendali, interruzione dell'attività, perdita di informazioni aziendali o altre perdite pecuniarie) derivanti dall'uso o dall'impossibilità di utilizzare gli script di esempio o la documentazione, anche se Microsoft è stato informato della possibilità di tali danni.

  1. Utilizzare il seguente script Windows PowerShell per ottenere un CCSID e un PCSID.

    #Saudi Arabian electronic invoice onboarding script
     #Version 1.1
     param($action, $endpoint, $otp, $csrconfig, $password)
     $env:path = $env:path + ";C:\Program Files\Git\usr\bin"
    
     $simulationEndpoint = 'https://gw-fatoora.zatca.gov.sa/e-invoicing/simulation'
     $prodEndpoint = 'https://gw-fatoora.zatca.gov.sa/e-invoicing/core'
    
     if ($endpoint -eq "simulation")
     {
     	$serviceEndpoint = $simulationEndpoint
     } elseif ($endpoint -eq "prod") {
     	$serviceEndpoint = $prodEndpoint
     } else {
     	Write-Host "`nMissing parameter (with values simulation/prod): endpoint"
     	Break
     }
    
     if ($action -eq "getComplianceCSID")
     {
     	if (-not (Test-Path -Path $csrconfig))
     	{
     		throw "CSR configuration file does not exist, please make sure to provide a valid file path for the '-csrconfig' parameter."
     	}
    
     	if ($otp -eq $null)
     	{
     		throw "OTP code is not provided, please carry correct parameters."
     	}
    
     	#Generate private key
     	openssl ecparam -name secp256k1 -genkey -noout -out privatekey.pem
     	Write-Host "Private key generated."
    
     	#Generate public key
     	openssl ec -in privatekey.pem -pubout -conv_form compressed -out publickey.pem
     	Write-Host "Public key generated."
    
     	#Generate CSR(Certificate signing request)
     	openssl base64 -d -in publickey.pem -out publickey.bin
     	openssl req -new -sha256 -key privatekey.pem -extensions v3_req -config $csrconfig -out .\taxpayer.csr 
     	openssl base64 -in taxpayer.csr -out taxpayerCSRbase64Encoded.txt
     	$CSRbase64Encoded = Get-Content -path taxpayerCSRbase64Encoded.txt -Raw
     	$CSRbase64Encoded = $CSRbase64Encoded -replace "`n",""
     	$CSRbase64Encoded = $CSRbase64Encoded -replace "`r",""
    
     	#Init request for CCSID
     	$postParams = @{"csr"=$CSRbase64Encoded} | ConvertTo-Json
     	$postHeader = @{
     		   "Accept"="application/json"
     		   "OTP"=$otp
     		   "Content-Type"="application/json"
     		   "Accept-Version"="V2"}
     	echo $CSRbase64Encoded
     	try
     	{
     		$response = Invoke-WebRequest -Uri $serviceEndpoint'/compliance' -Method POST -Body $postParams -Headers $postHeader 
     	}
     	catch
     	{
     		$respStream = $_.Exception.Response.GetResponseStream()
     		$reader = New-Object System.IO.StreamReader($respStream)
     		$respBody = $reader.ReadToEnd()
     		$reader.Close()
    
     		Write-Host "`nZatca service communication error:"
     		Write-Host $_.Exception.Message
     		Write-Host "Detailed error message: " $respBody
     		Write-Host "The process of obtaining a Compliance CSID (CCSID) is interrupted."
     	}
    
     	if ($response -ne $null)
     	{
     		$response = $response | ConvertFrom-Json
     		$requestId = $response.requestID
     		Write-Host "Request ID:"
     		Write-Host $requestId
     		$requestId | Out-File -FilePath .\requestId.txt -Encoding utf8 -NoNewline
    
     		$CCSIDbase64 = $response.binarySecurityToken
     		Write-Host "`nCompliance CSID received from Zatca:"
     		Write-Host $CCSIDbase64
     		$CCSID = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($CCSIDbase64))
     		$CCSIDCertString = "-----BEGIN CERTIFICATE-----`n" + $CCSID + "`n" + "-----END CERTIFICATE-----"
    
     		$CCSIDSecret = $response.secret
     		Write-Host "`nCompliance CSID secret received from Zatca:"
     		Write-Host $CCSIDSecret
    
     		$CCSIDStringFileName = "CCSIDString.txt"
     		$CCSIDSecretFileName = "CCSIDSecret.txt"
     		$CCSIDCertFileName = "CCSID.pem"
     		$CCSIDFolderPath = Get-Location
     		$CCSIDCertFilePath = Join-Path $CCSIDFolderPath $CCSIDCertFileName
     		$CCSIDStringFilePath = Join-Path $CCSIDFolderPath $CCSIDStringFileName
     		$CCSIDSecretFilePath = Join-Path $CCSIDFolderPath $CCSIDSecretFileName
    
     		$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
     		[System.IO.File]::WriteAllLines($CCSIDCertFilePath, $CCSIDCertString, $Utf8NoBomEncoding)
     		[System.IO.File]::WriteAllLines($CCSIDStringFilePath, $CCSIDbase64, $Utf8NoBomEncoding)
     		[System.IO.File]::WriteAllLines($CCSIDSecretFilePath, $CCSIDSecret, $Utf8NoBomEncoding)
    
     		openssl pkcs12 -inkey privatekey.pem -in CCSID.pem -export -passout pass:$password -out CCSID.pfx
     		Write-Host "`nCertificate is saved to CCSID.pfx file and secret is saved to CCSIDSecret.txt file."
     		Write-Host "The process of obtaining a Compliance CSID (CCSID) is complete, please process the compliance check and do not delete or move any created files before getting PCSID."
     	}
    
     }
    
    
     if ($action -eq "getProductionCSID")
     {
     	if (-not (Test-Path -Path requestId.txt))
     	{
     		throw "'requestId.txt' file is missing, please make sure you're running the script in the same location where the results of getting the CCSID are stored."
     	}
     	if (-not (Test-Path -Path CCSIDString.txt))
     	{
     		throw "'CCSIDString.txt' file is missing, please make sure you're running the script in the same location where the results of getting the CCSID are stored."
     	}
     	if (-not (Test-Path -Path CCSIDSecret.txt))
     	{
     		throw "'CCSIDSecret.txt' file is missing, please make sure you're running the script in the same location where the results of getting the CCSID are stored."
     	}
    
     	$requestId = Get-Content -path requestId.txt -Raw
     	$requestId = $requestId -replace "`n",""
     	$requestId = $requestId -replace "`r",""
     	Write-Host "Request ID is:" $requestId
     	$CCSID = Get-Content -path CCSIDString.txt -Raw
     	$CCSID = $CCSID -replace "`n",""
     	$CCSID = $CCSID -replace "`r",""
     	Write-Host "`nCompliance CSID read locally:"
     	Write-Host $CCSID
     	$CCSIDSecretString = Get-Content -path CCSIDSecret.txt -Raw
     	$CCSIDSecretString = $CCSIDSecretString -replace "`n",""
     	$CCSIDSecretString = $CCSIDSecretString -replace "`r",""
     	Write-Host "`nCompliance CSID secret read locally:"
     	Write-Host $CCSIDSecretString
     	$AuthTokenString = $CCSID + ":" + $CCSIDSecretString
     	$BasicAuthToken = "Basic " + [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($AuthTokenString))
    
     	#Init request for Production CSID (PCSID)
     	$postParams = @{"compliance_request_id"=$requestId} | ConvertTo-Json
     	$postHeader = @{
     		   "Accept"="application/json"
     		   "Authorization"=$BasicAuthToken
     		   "Content-Type"="application/json"
     		   "Accept-Version"="V2"}
    
     	try
     	{
     		$response = Invoke-WebRequest -Uri $serviceEndpoint'/production/csids' -Method POST -Body $postParams -Headers $postHeader
     	}
     	catch
     	{
     		$respStream = $_.Exception.Response.GetResponseStream()
     		$reader = New-Object System.IO.StreamReader($respStream)
     		$respBody = $reader.ReadToEnd()
     		$reader.Close() 
    
     		Write-Host "`nZatca service communication error:"
     		Write-Host $_.Exception.Message
     		Write-Host "Detailed error message: " $respBody 
     		Write-Host "Please make sure the compliance check process has been done before obtaining a Production CSID (PCSID)."
     		Write-Host "The process of obtaining a Production CSID (PCSID) is interrupted."
     	}
    
     	if ($response -ne $null)
     	{
     		$response = $response | ConvertFrom-Json
     		$PCSIDbase64 = $response.binarySecurityToken
     		Write-Host "`nProduction CSID received from Zatca:"
     		Write-Host $PCSIDbase64
    
     		$PCSID = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($PCSIDbase64))
     		$PCSIDCertString = "-----BEGIN CERTIFICATE-----`n" + $PCSID + "`n" + "-----END CERTIFICATE-----"
    
     		$PCSIDSecret = $response.secret
     		Write-Host "`nProduction CSID secret received from Zatca:"
     		Write-Host $PCSIDSecret
    
     		$PCSIDCertFileName = "PCSID.pem"
     		$PCSIDSecretFileName = "PCSIDSecret.txt"
     		$PCSIDFolderPath = Get-Location
     		$PCSIDCertFilePath = Join-Path $PCSIDFolderPath $PCSIDCertFileName
     		$PCSIDSecretFilePath = Join-Path $PCSIDFolderPath $PCSIDSecretFileName
    
     		$Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
     		[System.IO.File]::WriteAllLines($PCSIDCertFilePath, $PCSIDCertString, $Utf8NoBomEncoding)
     		[System.IO.File]::WriteAllLines($PCSIDSecretFilePath, $PCSIDSecret, $Utf8NoBomEncoding)
    
     		# Sandbox API will get error: openssl : No certificate matches private key
     		openssl pkcs12 -inkey privatekey.pem -in PCSID.pem -export -passout pass:$password -out PCSID.pfx
    
     		if (Test-Path -Path PCSID.pfx)
     		{
     			Write-Host "`nCertificate is saved to PCSID.pfx file and secret is saved to PCSIDSecret.txt file."
     			Write-Host "The process of obtaining a Production CSID (PCSID) is complete."
     		}
     		else
     		{
     			Write-Host "`nThe process of obtaining a Production CSID (PCSID) is interrupted."
     		}
     	}
     }
    
  2. Salvare il file del certificato .pfx di output ricevuto nel key vault.

Risorse aggiuntive