Chilkat HOME .NET Core C# Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi ActiveX Delphi DLL Go Java Lianja Mono C# Node.js Objective-C PHP ActiveX PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift 2 Swift 3,4,5... Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(Tcl) Send ZATCA Invoice for ClearanceSee more ZATCA ExamplesDemonstrates how to send a ZATCA invoice for clearance, which is to send the HTTP POST with invoice hash and the signed invoice in base64 format.
load ./chilkat.dll # This example requires the Chilkat API to have been previously unlocked. # See Global Unlock Sample for sample code. # This example will send a POST with HTTP Basic Authentication to # https://gw-fatoora.zatca.sa/e-invoicing/simulation/invoices/clearance/single # NOTE: At the time of this writing, I don't know for sure if the above URL is correct. # # The body of the POST will contain JSON formatted as such: # { # "summary": "Standard Invoice", # "value": { # "invoiceHash": "PEx8bNFcEMEpHzUVvQntQI6ot8eFqTT/l59b+H1HqX4=", # "uuid": "16e78469-64af-406d-9cfd-895e724198f0", # "invoice": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPEl....." # } # } # The above JSON is created from the signed XML invoice, such as the following: # *** Look at the above base64 data for the invoiceHash and uuid. These values are found in the invoice as shown below. # *** We'll write code to load the signed invoice into a Chilkat XML object, grab the invoice hash and the uuid, # *** and then construct the above JSON, which will then be sent in a POST. (See below...) # <?xml version="1.0" encoding="UTF-8"?> # <Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"><ext:UBLExtensions> # <ext:UBLExtension> # <ext:ExtensionURI>urn:oasis:names:specification:ubl:dsig:enveloped:xades</ext:ExtensionURI> # <ext:ExtensionContent> # <!-- Please note that the signature values are sample values only --> # <sig:UBLDocumentSignatures xmlns:sig="urn:oasis:names:specification:ubl:schema:xsd:CommonSignatureComponents-2" xmlns:sac="urn:oasis:names:specification:ubl:schema:xsd:SignatureAggregateComponents-2" xmlns:sbc="urn:oasis:names:specification:ubl:schema:xsd:SignatureBasicComponents-2"> # <sac:SignatureInformation> # <cbc:ID>urn:oasis:names:specification:ubl:signature:1</cbc:ID> # <sbc:ReferencedSignatureID>urn:oasis:names:specification:ubl:signature:Invoice</sbc:ReferencedSignatureID> # <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="signature"> # <ds:SignedInfo> # <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2006/12/xml-c14n11"/> # <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"/> # <ds:Reference Id="invoiceSignedData" URI=""> # <ds:Transforms> # <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"> # <ds:XPath>not(//ancestor-or-self::ext:UBLExtensions)</ds:XPath> # </ds:Transform> # <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"> # <ds:XPath>not(//ancestor-or-self::cac:Signature)</ds:XPath> # </ds:Transform> # <ds:Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"> # <ds:XPath>not(//ancestor-or-self::cac:AdditionalDocumentReference[cbc:ID='QR'])</ds:XPath> # </ds:Transform> # <ds:Transform Algorithm="http://www.w3.org/2006/12/xml-c14n11"/> # </ds:Transforms> # <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> # <ds:DigestValue>PEx8bNFcEMEpHzUVvQntQI6ot8eFqTT/l59b+H1HqX4=</ds:DigestValue> # </ds:Reference> # <ds:Reference Type="http://www.w3.org/2000/09/xmldsig#SignatureProperties" URI="#xadesSignedProperties"> # <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> # <ds:DigestValue>ZDEyMDUyODJjYzk4MGViNTJhNmYzMGIyZTgxODhkY2JlOWEzNmRiMTFlZTVhMDAxNjk5OTRkYTg3ODhlY2ZiMw==</ds:DigestValue> # </ds:Reference> # </ds:SignedInfo> # ... # ... # ... # </ext:ExtensionContent> # </ext:UBLExtension> # </ext:UBLExtensions> # # <cbc:ProfileID>reporting:1.0</cbc:ProfileID> # <cbc:ID>SME00062</cbc:ID> # <cbc:UUID>16e78469-64af-406d-9cfd-895e724198f0</cbc:UUID> # <cbc:IssueDate>2022-03-13</cbc:IssueDate> # <cbc:IssueTime>14:40:40</cbc:IssueTime> # <cbc:InvoiceTypeCode name="0111010">388</cbc:InvoiceTypeCode> # ... # ... # ... # </cac:InvoiceLine> # </Invoice> # ------------------------------------------------------------------- # First, let's load our signed XML into a Chilkat XML object so we can get the uuid and invoice hash. set signedXmlFilePath "qa_data/zatca/http_post_clearance/sample_signed_invoice.xml" set signedXml [new_CkXml] set success [CkXml_LoadXmlFile $signedXml $signedXmlFilePath] if {$success == 0} then { puts [CkXml_lastErrorText $signedXml] delete_CkXml $signedXml exit } set invoiceHash [CkXml_getChildContent $signedXml "ext:UBLExtensions|ext:UBLExtension|ext:ExtensionContent|sig:UBLDocumentSignatures|sac:SignatureInformation|ds:Signature|ds:SignedInfo|ds:Reference[0]|ds:DigestValue"] puts "invoiceHash: $invoiceHash" set cbc_UUID [CkXml_getChildContent $signedXml "cbc:UUID"] puts "UUID: $cbc_UUID" # The Chilkat XML object was used purely for getting the above 2 values. # We must send the EXACT signed XML in base64 format. Therefore, we should load the signed XML into a Chilkat BinData and get it in base64 single-line format. set bd [new_CkBinData] set success [CkBinData_LoadFile $bd $signedXmlFilePath] set base64Invoice [CkBinData_getEncoded $bd "base64"] # OK, let's build the JSON that will be in the HTTP POST body. set json [new_CkJsonObject] CkJsonObject_UpdateString $json "summary" "Standard Invoice" CkJsonObject_UpdateString $json "value.invoiceHash" $invoiceHash CkJsonObject_UpdateString $json "value.uuid" $cbc_UUID CkJsonObject_UpdateString $json "value.invoice" $base64Invoice # Now create the HTTP object and send the POST. set http [new_CkHttp] # We'll want HTTP basic authentication. CkHttp_put_BasicAuth $http 1 CkHttp_put_Login $http "your login" CkHttp_put_Password $http "your password" # resp is a CkHttpResponse set resp [CkHttp_PostJson3 $http "https://gw-fatoora.zatca.sa/e-invoicing/simulation/invoices/clearance/single" "application/json" $json] if {[CkHttp_get_LastMethodSuccess $http] == 0} then { puts [CkHttp_lastErrorText $http] delete_CkXml $signedXml delete_CkBinData $bd delete_CkJsonObject $json delete_CkHttp $http exit } # Check the response status code. A 200 or 202 indicates success.. set statusCode [CkHttpResponse_get_StatusCode $resp] puts "Response status code = $statusCode" # Examine the response, which is JSON. set jsonResp [new_CkJsonObject] CkHttpResponse_GetBodyJson $resp $jsonResp CkJsonObject_put_EmitCompact $jsonResp 0 puts "JSON Response:" puts [CkJsonObject_emit $jsonResp] # Use this online tool to generate parsing code from sample JSON: # Generate Parsing Code from JSON delete_CkXml $signedXml delete_CkBinData $bd delete_CkJsonObject $json delete_CkHttp $http delete_CkJsonObject $jsonResp |
© 2000-2024 Chilkat Software, Inc. All Rights Reserved.