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:
- Hae YHTEENSOPIVUUS CSID (CCSID), jonka ZATCA määrittää tarkistamaan sähköisen laskun luonnin ratkaisujen (sähköisten laskujen luontiratkaisut) yhteensopivuustarkistukset.
- Hanki TUOTANTO CSID (PCSID), jonka ZATCA määrittää vaatimusten mukaisille SEN KÄYTTÄJILLE.
CCSID-tietojen hankkiminen
Siirry Saudi-Arabian verotusportaalissa (Y-y-portaali) ja valitse haluamasi ruutu Onboarding and Management Portalista.
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.
Valitse generoimaan OTP-koodien määrä. Määrä riippuu käytettävästä laskutuksen luontiyksiköistä (laitteista).
Tallenna luodut OTP-koodit, jotta voit käyttää niitä myöhemmin.
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
Tallenna tiedosto samaan sijaintiin kuin komentotiedostoon, jolla on nimi ja csr_config.txt .
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.
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.
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.
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.
Varmista, että kaikki sähköiset laskut on lähetetty ZATCA-toimittajalle.
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.
PCSID vastaanotetaan sertifikaattitiedostona PSERTIFIKAATIT-muodossa. Tallenna tämä PCSID-todistus ja sen tiedosto Azure avaimen näppäimeen.
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.
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." } } }
Tallenna tuotoksen .psignaalin sertifikaattitiedosto, joka vastaanotetaan avaimen avaimen avarista.