Onboarding van elektronische facturering in Saoedi-Arabië
Aan boord maken is verplicht voor alle belastingbetalers die onderworpen elektronische facturering saudi-Arabië. Als gevolg van het aan boord maken, ontvangen belastingbetalers cryptografische stempel-ID's (DUSDs). ER ZIJN SINGD's vereist voor integratie met elektronische facturering portal dat wordt beheerd door de Saudi-Arabische belastingdienst () en voor verdere verzending van elektronische facturen.
In dit artikel wordt uitgelegd hoe u belastingbetalers en hun elektronische facturering aan te nemen bij de Saudi-Arabische belastingdienst.
Vereisten
- De rechtspersoon moet zijn geregistreerd als belastingplichtige in Saudi-Arabië en moet een geldig btw-registratienummer (belasting toegevoegde waarde) hebben.
- De rechtspersoon moet toegang hebben tot het ERAD (Saudi-Arabië Tax Portal).
Onboarding-proces
Het aan boord nemen bestaat uit twee stappen:
- Een COMPLIANCE CCSID (Compliance CCSID) verkrijgen, dat DOORNca toewijst om conformiteitscontroles uit te voeren op oplossingen voor het genereren van elektronische facturen (EGSs).
- Een PCSID (production ERPD) verkrijgen, dat DOOR ERCA aan compatibele VSS's toewijst.
Een CCSID verkrijgen
Ga in het ERAD (Saudi-Arabië) naar de Aanmelding en het Management Portal door het relevante portaal te selecteren.
Selecteer op de hoofdpagina van de Aanmelding en Management Portal de aanmeldbare nieuwe oplossingseenheid/ -apparaat en selecteer vervolgens OTP-code genereren. De OTP-code is slechts één uur geldig nadat deze is gegenereerd. Zorg ervoor dat deze binnen die tijd wordt frame.
Het aantal eentijdswachtwoordcodes (OTP)-codes selecteren dat u wilt genereren. Het aantal is afhankelijk van het aantal eenheden voor het genereren van e-facturering (apparaten) dat wordt gebruikt.
Sla de gegenereerde OTP-codes op, zodat u ze in latere stappen kunt gebruiken.
Een configuratiebestand voorbereiden voor het ondertekeningsverzoek voor het certificaat. Dit configuratiebestand moet de vorm hebben van een tekstbestand met de volgende gegevens.
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
Sla het bestand op dezelfde locatie op als het script op script met de naam,csr_config.txt .
Werk in het configuratiebestand de e-mailAddress-waarde en de volgende specifieke gegevens bij.
Code Description Specificatie E De land-/regiocode. Een code van twee letters (ISO 3166 Alfa-2) OU De naam van de organisatie-eenheid. Voor normale belastingbetalers is de waarde vrije tekst. Voor btw-groepen identificeren cijfers de waarde met het tiental cijfers van de organisatie-ID met '1'. Valideer dat de invoer een 10-cijferig btw-identificatienummer is. O De naam van de organisatie of belastingbetaler. Vrije tekst CN De unieke naam van de oplossing of eenheid. Vrije tekst SN De unieke identificatiecode voor de oplossing. Vrije tekst UID Het btw-registratienummer van de belastingbetaler. Vijftien cijfers. Dit nummer begint met 3 en eindigt met 3. titel Het documenttype dat door de oplossingseenheid van de belastingbetaler wordt uitgeven. Numerieke invoer van vier cijfers met de waarde '0' en '1' die is toekend aan TSUPDATE: 0 = Onwaar/Niet ondersteund, 1 = Waar/Ondersteund. T = btw-factuur (standaard), S = Vereenvoudigde btw-factuur, C = Voor toekomstig gebruik, Z = Voor toekomstig gebruik. registeredAddress Het adres van de vestiging of locatie waar het apparaat of de oplossingseenheid zich voornamelijk bevindt. Vrije tekst businessCategory De bedrijfstak of sector waar het apparaat of de oplossing facturen voor zal genereren. Vrije tekst Notitie
De waarden voor ERS en certificaatTemplateName in het config-bestand verschillen wanneer u de simulatieportal gebruikt.
In de simulatieportal:
- BEDRIJFSTAK - PREZATCA-Code-Signing
- certificateTemplateName - ASN1:PRINTABLESTRING:PREZATCA-Code-Signing
Gebruik voor alle andere gevallen de bovenstaande waarden.
Voer het aanmaningsscript uit dat later in dit artikel wordt gegeven. Geef de OTP en het configuratiebestand op als invoerparameters. Hieronder is een voorbeeld: script heeft twee mogelijke eindpuntsimulatie en prod.
.\OnboardingScript.ps1 -action getComplianceCSID -endpoint prod -otp 123345 -csrconfig .\csr_config.txt -password 123
Notitie
De wachtwoordparameter is optioneel en kan worden weggelaten. Als dit is opgenomen, heeft het certificaat dat wordt gegenereerd het opgegeven wachtwoord.
De CCSID wordt ontvangen als certificaatbestand 'CCSID.pfx' en de ccSID wordt opgeslagen als 'CCSIDSecret.txt'. Sla dit CCSID-certificaatbestand op in het Microsoft Azure certificaat van het belangrijkste certificaat en sla de licentie op in de sleutel worden opgeslagen. Microsoft Azure Zie Klantcertificaten en -diploma's voor meer informatie.
Configureer de gerelateerde functie-instellingen in de functie voor de conformiteitscontrole (SAUDI-Arabië) elektronische facturering en verwijs naar het CCSID-certificaat dat u in de sleutel opgeslagen hebt. Het certificaat wordt gebruikt voor communicatie met de ELEKTRONISCHE FACTURERING portal.
Conformiteitscontrole
Nadat u conformiteitS-VSD hebt ontvangen met behulp van het PowerShell-script, vereist ERCA dat u bepaalde conformiteitscontroles moet voltooien door voorbeeldfacturen in te dienen. Dit stap is een vereiste voor het aanvragen van een PRODUCTIE-VSD.
Zorg ervoor dat alle typen voorbeeldfacturen die zijn geconfigureerd in het configuratiebestand Certificate Signing Request (VSR) zijn geconfigureerd, naar ERCA zijn verzonden. Gebruik het standaardproces voor het uitgeven van elektronische facturen. Zie Uitgifte van elektronische facturen in Financiën en toeleveringsketen meer informatie.
gebruik de functie'S saudi-Arabië een conformiteitscontrole (INDIENN)" in RCS en volgen de land -/regiospecifieke configuratiesectiestappen met behulp van de door u verkregen CONFORMITEITS-
Nadat de conformiteitscontroles met succes zijn voltooid, gebruikt u het PowerShell-script om productie-ERFD te verkrijgen (refer on-script).
Notitie
Als het documenttype van het configuratiebestand op 1000 wordtingesteld in het veld Titel, moeten drie voorbeeldfacturen worden ingediend voor de conformiteitscontrole:
- Standaard-btw-factuur
- Standaarddebetnota
- Standaardcreditnota
Als het documenttype van het configuratiebestand in het veld Titel is ingesteld op 0100, moeten drie voorbeeldfacturen worden ingediend voor de conformiteitscontrole:
- Vereenvoudigde btw-factuur
- Vereenvoudigde debetnota
- Vereenvoudigde creditnota
Als het documenttype is ingesteld op 1100, moeten alle zes de voorbeeldfacturen worden ingediend voor de conformiteitscontrole.
Een PCSID verkrijgen
Om een PCSID te verkrijgen, moet u de oplossing correct configureren voor het genereren en indienen van elektronische facturen. De oplossing moet volledig werken. Om dit resultaat te bereiken, moet u alle vereiste voorlopige configuratiestappen voltooien. Zie Aan de slag met elektronische facturering voor Saudi-Arabië voor meer informatie.
Zorg ervoor dat alle elektronische facturen naar WORDTCA zijn verzonden.
Voer het aanmaningsscript uit dat later in dit artikel wordt gegeven. De CCSID als invoerparameter opgeven. Hieronder is een voorbeeld: script heeft twee mogelijke eindpuntsimulatie & prod
.\OnboardingScript.ps1 -action getProductionCSID -endpoint prod -password 123
Notitie
De wachtwoordparameter is optioneel en kan worden weggelaten. Als dit is opgenomen, heeft het certificaat dat wordt gegenereerd het opgegeven wachtwoord.
De PCSID wordt ontvangen als certificaatbestand in PFX-indeling. Sla dit PCSID-certificaat en bestand op in het Azure van de sleutel.
Configureer de gerelateerde functie-instellingen in de functie voor de saudi-Arabië-Eredinzending (ELEKTRONISCHE FACTURERING ). Voeg het PCSID-certificaat en deze toe aan de belangrijkste parameters voor parameters voor parameters in HET PCSID-certificaat.
Nadat u alle configuratiestappen hebt voltooid, is het systeem klaar om te worden gebruikt in de productiemodus.
Voor het controleren van verkregen ERP's aan de HIERCA-kant, gebruikt u de ERD (Review Existing Cryptographic Stamp Identifier) op de pagina van de Aanmelding en Management Portal. Deze portal is toegankelijk via de belangrijkste ERAD (Saudi-Arabië-belastingportal).
Aanmaningsscript
Notitie
De voorbeeldscripts worden niet ondersteund onder een Microsoft-ondersteuningsprogramma of -service. De voorbeeldscripts worden as is geleverd zonder garantie van welke soort dan ook. Microsoft wijst alle impliciete garanties verder af, met inbegrip van, zonder beperking, impliciete garanties van verhandelbaarheid of geschiktheid voor een bepaald doel. Het hele risico dat het gebruik of de prestaties van de voorbeeldscripts en documentatie bij u in het systeem ontstaan. In geen geval zal Microsoft, de auteurs, of iemand anders die betrokken zijn bij het maken, produceren of afleveren van de scripts verantwoordelijk zijn voor eventuele schade (inclusief, zonder beperking, schade voor verlies van bedrijfswinsten, bedrijfswinst, verlies van bedrijfsgegevens of ander pecuniary loss) die het gevolg is van het gebruik van of het onvermogen om de voorbeeldscripts of documentatie te gebruiken, zelfs als Microsoft op de hoogte is van de mogelijkheid van dergelijke schade.
Gebruik het volgende Windows PowerShell script om een CCSID en een PCSID te verkrijgen.
#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." } } }
Sla het bestand met het PFX-uitvoercertificaat op dat wordt ontvangen in het sleutelbestand.