Jaa


Saudi-Arabian sähköisen laskutuksen käyttöönotto

Onboarding on pakollinen kaikille verovelvollisille, joita sähköinen laskutus Saudi-Arabiassa. Mukana on mukana mukana prosessi, jossa verovelvolliset saavat kryptografisia leimatunnuksia (CSIDs). CSID-tunnukset on integroitava Saudi sähköinen laskutus-arabian veroviranomaisen (ZATCA) hallitsemaan sähköinen laskutus-portaaliin sekä sähköisten laskujen lisälähetykseen.

Tässä artikkelissa kerrotaan, miten verovelvolliset ja heidän sähköinen laskutus saudi-arabian veroviranomaisten kanssa.

Edellytykset

  • Oikeushenkilö on rekisteröitävä saudi-arabialainen verovelvollinen, ja sillä on oltava voimassa oleva arvonlisäveron rekisterinumero.
  • Yrityksellä on oltava oikeus käyttää Saudi-Arabian verotusportaalia (TIETUEET).

Mukanamisprosessi

Mukana on kaksi vaihetta:

  1. Hae YHTEENSOPIVUUS CSID (CCSID), jonka ZATCA määrittää tarkistamaan sähköisen laskun luonnin ratkaisujen (sähköisten laskujen luontiratkaisut) yhteensopivuustarkistukset.
  2. Hanki TUOTANTO CSID (PCSID), jonka ZATCA määrittää vaatimusten mukaisille SEN KÄYTTÄJILLE.

Mukana -työnkulku.

CCSID-tietojen hankkiminen

  1. Siirry Saudi-Arabian verotusportaalissa (Y-y-portaali) ja valitse haluamasi ruutu Onboarding and Management Portalista.

  2. Valitse Mukana oleva uusi ratkaisuyksikkö/laite -ruutu ja valitse sitten Luo OTP-koodi lisäyksiköstä ja -hallintaportaalin pääaimista. OTP-koodi on voimassa vain yhden tunnin ajan sen luomisen jälkeen. Varmista, että sitä käytetään tässä ajassa.

  3. Valitse generoimaan OTP-koodien määrä. Määrä riippuu käytettävästä laskutuksen luontiyksiköistä (laitteista).

  4. Tallenna luodut OTP-koodit, jotta voit käyttää niitä myöhemmin.

  5. Valmistele konfigurointitiedosto sertifikaatin allekirjoituspyyntöä varten. Tämän konfigurointitiedoston tulee olla tavallinen tekstitiedosto, joka sisältää seuraavat tiedot.

    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. Tallenna tiedosto samaan sijaintiin kuin komentotiedostoon, jolla on nimi ja csr_config.txt .

  7. Päivitä konfigurointitiedostossa emailAddress-arvo ja seuraavat tiedot.

    Koodi kuvaus Määritys
    Y Maan/alueen koodi. Kaksikirjaiminen koodi (ISO 3166 Alpha-2)
    OU Organisaatioyksikön nimi. Normaalien verovelvollisten arvo on vapaateksti. Määritä arvonlisäveroryhmien arvo sen organisaatiotunnuksen 11.11. numeron avulla, joka on "1". Vahvista, että syöte on 10-numeroinen verotunnusnumero.
    O Organisaation tai verovelvollisen nimi. Vapaa teksti
    CN Ratkaisun tai yksikön yksilöivä nimi. Vapaa teksti
    SN Ratkaisun yksilöivä tunnuskoodi. Vapaa teksti
    UID-tunnus Verovelvollisen alv-rekisterinumero. Viisitoista numeroa. Tämä numero alkaa numerosta "3" ja päättyy numeroon "3".
    otsikko Asiakirjatyyppi, jonka verovelvollisen ratkaisuyksikkö antaa. Nelinumeroinen numeerinen syöte, joka käyttää numeroita "0" ja "1", jotka on yhdistetty kohteeseen "TSUI": 0 = False/Not supported, 1 = True/Supported. T = Verolasku (vakio), S = Yksinkertaistettu verolasku, C = Tulevaa käyttöä varten, Z = Tulevaa käyttöä varten.
    registeredAddress. Sen haaran tai sijainnin osoite, jossa laite tai ratkaisuyksikkö sijaitsee etupäässä. Vapaa teksti
    liiketoimintaluokka Toimiala tai sektori, jota varten laite tai ratkaisu luo laskuja. Vapaa teksti

    Muistiinpano

    KONFIGUROINTITIEDOSTONMÄÄRITYKSET JA certificateTemplateName-arvot eivät ole erilaiset, kun käytät simulointiportaalia.

    Simulointiportaalissa:

    • ESPANJA - PREZAHTCA-Koodi-allekirjoitus
    • certificateTemplateName - ASN1:PRINTABLESTRING:PREZAHTCA-Koodi-allekirjoitus

    Käytä arvoja yllä kuvatuissa tapauksissa.

  8. Suorita mukana seuraavassa tässä artikkelissa annettu komentotiedosto. Määritä OTP- ja konfigurointitiedosto syöttöparametreja varten. Tässä on esimerkki: Komentosarjalla on kaksi mahdollista päätepistettä simuloinnissa ja prodissa .

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

    Muistiinpano

    Salasanaparametri on valinnainen, ja sen voi jättää pois. Jos se sisältyy, luodulla todistuksella on määritetty salasana.

  9. CCSID vastaanotetaan sertifikaattitiedostona "CCSID.p myös", ja CCSID:n allekirjoitus tallennetaan txt-tiedostona "CCSIDSecret.txt". Tallenna tämä CCSID-todistustiedosto avaimen Microsoft Azure sertifikaattiin ja tallenna Sen Microsoft Azure sertifikaatti avaimen, ylle. Lisätietoja on asiakkaan todistuksissa ja todistuksissa.

  10. Määritä asiaan liittyvät toimintoasetukset Saudi-Arabian ZATCA compliance check (SA) -sähköinen laskutusominaisuuden avulla ja viittaus avainsäilöön tallennettuun CCSID-sertifikaattiin. Sertifikaattia käytetään viestintään ZATCA-sähköinen laskutus kanssa.

Yhteensopivuuden tarkistus

Kun olet hankkinut Yhteensopivuuden CSID:n käyttämällä PowerShell komentosarjaa, ZATCA edellyttää tiettyjen yhteensopivuustarkistuksen lähettämistä esimerkkilaskuja. Tämä vaihe edellyttää tuotannon CSID-pyynnön pyytämista.

Varmista, että kaikkien sertifikaatin allekirjoituspyynnön (CSR) konfiguroinnin mallilaskujen tyypit lähetetään ZATCA-mallitiedostoon onnistuneesti. Käytä sähköisten laskujen sähköisten laskujen vakiolaskujen kirjausprosessia. Lisätietoja on myyntitiedot ja laskujen hallinnan kohdassa Sähköisten toimitusketju.

Käytä RCS:ssä toimintoa "Saudi-Arabian ZATCA compliance check (SA)" ja noudata maa- ja aluekohtainen konfigurointi -vaiheita käyttämällä saamiasi Yhteensopivuuden CSID-ohjeita.

Kun yhteensopivuustarkistukset on suoritettu onnistuneesti, hae PowerShell -komentosarjalla tuotannon CSID (lisätietoja on taulussa -komentotiedostossa).

Muistiinpano

Jos konfigurointitiedoston tiedostotyypiksi on määritetty 1000 Otsikko-kentässä, yhteensopivuustarkistusta varten on toimitettava kolme esimerkkilaskua:

  • Vakioverolasku
  • Vakioveloituslasku
  • Vakiohyvityslasku

Jos konfigurointitiedoston tiedostotyypiksi on määritetty Otsikko-kentässä 0100, yhteensopivuustarkistusta varten on toimitettava kolme esimerkkilaskua:

  • Verolaskun yksinkertaistaminen
  • Yksinkertaistettu veloituslasku
  • Yksinkertaisempi hyvityslasku

Jos tiedostotyypiksi on määritetty 1100, kaikki kuusi esimerkkilaskua on toimitettava yhteensopivuustarkistusta varten.

PCSID-tietojen hankkiminen

Ennen PCSID-järjestelmän hankkimista sinun on määritettävä sähköisen laskun luonnin ja lähetyksen ratkaisu oikein, ja ratkaisun on oltava täysin toimiva. Tämän tavoitteen saavuttamiseksi on suoritettava kaikki tarvittavat alustavat konfigurointivaiheet. Lisätietoja on kohdassa Saudi-Arabian sähköinen laskutus käytön aloittaminen.

  1. Varmista, että kaikki sähköiset laskut on lähetetty ZATCA-toimittajalle.

  2. Suorita mukana seuraavassa tässä artikkelissa annettu komentotiedosto. Määritä CCSID syöttöparametrina. Seuraavassa on esimerkki: Komentosarjalla on kaksi mahdollista päätepistettä simuloinnissa ja prodissa.

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

    Muistiinpano

    Salasanaparametri on valinnainen, ja sen voi jättää pois. Jos se sisältyy, luodulla todistuksella on määritetty salasana.

  3. PCSID vastaanotetaan sertifikaattitiedostona PSERTIFIKAATIT-muodossa. Tallenna tämä PCSID-todistus ja sen tiedosto Azure avaimen näppäimeen.

  4. Määritä liittyvät toimintoasetukset Saudi-Arabian Zatca submission (SA) sähköinen laskutus aikana. Sisällytä PCSID-todistus jamia RCS:n tärkeimpiin rcS-parametreihin.

Kun olet suorittanut kaikki konfiguraatiovaiheet, järjestelmä on valmis käyttöön tuotantotilassa.

Jos haluat tarkistaa saapuneet CSI-tunnukset ZATCA-puolelta, käytä Tutustu aiemmin luotuun kryptografisen leimatunnuksen (CSID) ruudussa sivuun Onboarding and Management Portal. Tämä portaali on käytettävissä Saudi-Arabian verotuksen pääportaalista (TÄSSÄ PORTAALISSA).

Mukana -komentosarja

Muistiinpano

Esimerkkikomentosarjoja ei tueta missään Microsoft vakio-tukiohjelmassa tai -palvelussa. Esimerkkikomentosarjat toimitetaan AS IS:nä ilman takuuta. Microsoft poistaa lisäksi kaikki epäsuorat takuet mukaan lukien kaikki epäsuorat takuet, jotka koskevat myyntikelpoisuutta tai myytävyyttä tiettyyn tarkoitukseen. Koko mallikomentosarjojen ja -dokumentaation käytöstä tai suorituskyvystä aiheutuva riski jää sinulle. Microsoft, sen tekijä tai muu, joka osallistuu komentosarjojen luomiseen, tuotantoon tai toimitukseen, ei missään tapauksessa ole vastuussa mistään vahingoista (mukaan lukien rajoituksetta liiketoiminnan voittojen menetyksestä, liiketoiminnan keskeytyksistä, liiketoimintatietojen menetyksestä tai muusta rahahävosta), joka voi syntyä näytekomentosarjojen tai -dokumentaation käytöstä tai siitä, että niitä ei voi käyttää. vaikka Microsoft on annettu kehotettavaksi näiden vahingon mahdollisuus.

  1. Hanki CCSID- ja PCSID-PowerShell Windows PowerShell -komentosarjalla.

    #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. Tallenna tuotoksen .psignaalin sertifikaattitiedosto, joka vastaanotetaan avaimen avaimen avarista.

Lisäresurssit