DataFlex
DataFlex
Create ITIDA Signed JSON and Send to ETA (Egypt Tax Authority) Portal
See more Egypt ITIDA Examples
Demonstrates how to create a .p7s signature that fits Egypt's ITIDA requirements where Chilkat automatically does the ITIDA JSON canonicalization. Also shows the code to send to the ETA Portal.Chilkat DataFlex Downloads
Use ChilkatAx-win32.pkg
Procedure Test
Boolean iSuccess
Handle hoCrypt
Variant vCert
Handle hoCert
Handle hoCmsOptions
Handle hoJsonSigningAttrs
Handle hoJson
String sJsonToSign
String sSigBase64
Handle hoSbToSend
String sClientId
String sClientSecretKey
Handle hoHttp
Variant vReq
Handle hoReq
Variant vResp
Handle hoResp
Token Handle hoJsonToken
String sAccessToken
String sJsonStr
String sUrl
String sTemp1
Integer iTemp1
Boolean bTemp1
Move False To iSuccess
// This example assumes the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
Get Create (RefClass(cComChilkatCrypt2)) To hoCrypt
If (Not(IsComObjectCreated(hoCrypt))) Begin
Send CreateComObject of hoCrypt
End
Set ComVerboseLogging Of hoCrypt To True
Get Create (RefClass(cComChilkatCert)) To hoCert
If (Not(IsComObjectCreated(hoCert))) Begin
Send CreateComObject of hoCert
End
Set ComVerboseLogging Of hoCert To True
// Set the smart card PIN, which will be needed for signing.
Set ComSmartCardPin Of hoCert To "12345678"
// There are many ways to load the certificate.
// This example was created for a customer using an ePass2003 USB token.
// Assuming the USB token is the only source of a hardware-based private key..
Get ComLoadFromSmartcard Of hoCert "" To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoCert To sTemp1
Showln sTemp1
Procedure_Return
End
// Tell the crypt class to use this cert.
Get pvComObject of hoCert to vCert
Get ComSetSigningCert Of hoCrypt vCert To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoCrypt To sTemp1
Showln sTemp1
Procedure_Return
End
Get Create (RefClass(cComChilkatJsonObject)) To hoCmsOptions
If (Not(IsComObjectCreated(hoCmsOptions))) Begin
Send CreateComObject of hoCmsOptions
End
// Setting "DigestData" causes OID 1.2.840.113549.1.7.5 (digestData) to be used.
Get ComUpdateBool Of hoCmsOptions "DigestData" True To iSuccess
Get ComUpdateBool Of hoCmsOptions "OmitAlgorithmIdNull" True To iSuccess
// Indicate that we are passing normal JSON and we want Chilkat do automatically
// do the ITIDA JSON canonicalization:
Get ComUpdateBool Of hoCmsOptions "CanonicalizeITIDA" True To iSuccess
Get ComEmit Of hoCmsOptions To sTemp1
Set ComCmsOptions Of hoCrypt To sTemp1
// The CadesEnabled property applies to all methods that create CMS/PKCS7 signatures.
// To create a CAdES-BES signature, set this property equal to true.
Set ComCadesEnabled Of hoCrypt To True
Set ComHashAlgorithm Of hoCrypt To "sha256"
Get Create (RefClass(cComChilkatJsonObject)) To hoJsonSigningAttrs
If (Not(IsComObjectCreated(hoJsonSigningAttrs))) Begin
Send CreateComObject of hoJsonSigningAttrs
End
Get ComUpdateInt Of hoJsonSigningAttrs "contentType" 1 To iSuccess
Get ComUpdateInt Of hoJsonSigningAttrs "signingTime" 1 To iSuccess
Get ComUpdateInt Of hoJsonSigningAttrs "messageDigest" 1 To iSuccess
Get ComUpdateInt Of hoJsonSigningAttrs "signingCertificateV2" 1 To iSuccess
Get ComEmit Of hoJsonSigningAttrs To sTemp1
Set ComSigningAttributes Of hoCrypt To sTemp1
// By default, all the certs in the chain of authentication are included in the signature.
// If desired, we can choose to only include the signing certificate:
Set ComIncludeCertChain Of hoCrypt To False
// Pass a JSON document such as the following. Chilkat will do the ITIDA canonicalization.
// (It is the canonicalized JSON that gets signed.)
// {
// "issuer":{
// "address":{
// "branchID":"0",
// "country":"EG",
// "regionCity":"Cairo",
// "postalCode":"",
// "buildingNumber":"0",
// "street":"123rd Street",
// "governate":"GOVERNATE"
// },
// "type":"B",
// "id":"209999899",
// "name":"Xyz SAE"
// },
// "receiver":{
// "address":{
// "country":"EG",
// "regionCity":"CAIRO",
// "postalCode":"11435",
// "buildingNumber":"0",
// "street":"Autostrad Road Abc",
// "governate":"GOVERNATE"
// },
// "type":"B",
// "id":"999999999",
// "name":"XYZ EGYPT FOR TRADE"
// },
// "documentType":"I",
// "documentTypeVersion":"1.0",
// "dateTimeIssued":"2020-11-15T11:04:53Z",
// "taxpayerActivityCode":"1073",
// "internalID":"ZZZZ999",
// "purchaseOrderReference":"2009199918",
// "salesOrderReference":"",
// "payment":{
// "bankName":"",
// "bankAddress":"",
// "bankAccountNo":"",
// "bankAccountIBAN":"",
// "swiftCode":"",
// "terms":""
// },
// "delivery":{
// "approach":"",
// "packaging":"",
// "dateValidity":"",
// "exportPort":"",
// "countryOfOrigin":"EG",
// "grossWeight":0,
// "netWeight":0,
// "terms":""
// },
// "invoiceLines":[
// {
// "description":"CDM Widget 48GX99X12BA",
// "itemType":"GS1",
// "itemCode":"7622213335056",
// "unitType":"CS",
// "quantity":1.00,
// "unitValue":{
// "currencySold":"EGP",
// "amountEGP":588.67,
// "amountSold":0,
// "currencyExchangeRate":0
// },
// "salesTotal":588.67,
// "total":603.97,
// "valueDifference":0,
// "totalTaxableFees":0,
// "netTotal":529.8,
// "itemsDiscount":0,
// "discount":{
// "rate":10.00,
// "amount":58.87
// },
// "taxableItems":[
// {
// "taxType":"T1",
// "amount":74.17,
// "subType":"No sub",
// "rate":14.00
// }
// ],
// "internalCode":"9099994"
// }
// ],
// "totalSales":588.67,
// "totalSalesAmount":588.67,
// "totalDiscountAmount":58.87,
// "netAmount":529.80,
// "taxTotals":[
// {
// "taxType":"T1",
// "amount":74.17
// }
// ],
// "extraDiscountAmount":0,
// "totalItemsDiscountAmount":0,
// "totalAmount":603.97,
// }
// Build the above JSON..
// Use this online tool to generate code from sample JSON:
// Generate Code to Create JSON
Get Create (RefClass(cComChilkatJsonObject)) To hoJson
If (Not(IsComObjectCreated(hoJson))) Begin
Send CreateComObject of hoJson
End
Get ComUpdateString Of hoJson "issuer.address.branchID" "0" To iSuccess
Get ComUpdateString Of hoJson "issuer.address.country" "EG" To iSuccess
Get ComUpdateString Of hoJson "issuer.address.regionCity" "Cairo" To iSuccess
Get ComUpdateString Of hoJson "issuer.address.postalCode" "" To iSuccess
Get ComUpdateString Of hoJson "issuer.address.buildingNumber" "0" To iSuccess
Get ComUpdateString Of hoJson "issuer.address.street" "123rd Street" To iSuccess
Get ComUpdateString Of hoJson "issuer.address.governate" "GOVERNATE" To iSuccess
Get ComUpdateString Of hoJson "issuer.type" "B" To iSuccess
Get ComUpdateString Of hoJson "issuer.id" "209999899" To iSuccess
Get ComUpdateString Of hoJson "issuer.name" "Xyz SAE" To iSuccess
Get ComUpdateString Of hoJson "receiver.address.country" "EG" To iSuccess
Get ComUpdateString Of hoJson "receiver.address.regionCity" "CAIRO" To iSuccess
Get ComUpdateString Of hoJson "receiver.address.postalCode" "11435" To iSuccess
Get ComUpdateString Of hoJson "receiver.address.buildingNumber" "0" To iSuccess
Get ComUpdateString Of hoJson "receiver.address.street" "Autostrad Road Abc" To iSuccess
Get ComUpdateString Of hoJson "receiver.address.governate" "GOVERNATE" To iSuccess
Get ComUpdateString Of hoJson "receiver.type" "B" To iSuccess
Get ComUpdateString Of hoJson "receiver.id" "999999999" To iSuccess
Get ComUpdateString Of hoJson "receiver.name" "XYZ EGYPT FOR TRADE" To iSuccess
Get ComUpdateString Of hoJson "documentType" "I" To iSuccess
Get ComUpdateString Of hoJson "documentTypeVersion" "1.0" To iSuccess
Get ComUpdateString Of hoJson "dateTimeIssued" "2020-11-15T11:04:53Z" To iSuccess
Get ComUpdateString Of hoJson "taxpayerActivityCode" "1073" To iSuccess
Get ComUpdateString Of hoJson "internalID" "ZZZZ999" To iSuccess
Get ComUpdateString Of hoJson "purchaseOrderReference" "2009199918" To iSuccess
Get ComUpdateString Of hoJson "salesOrderReference" "" To iSuccess
Get ComUpdateString Of hoJson "payment.bankName" "" To iSuccess
Get ComUpdateString Of hoJson "payment.bankAddress" "" To iSuccess
Get ComUpdateString Of hoJson "payment.bankAccountNo" "" To iSuccess
Get ComUpdateString Of hoJson "payment.bankAccountIBAN" "" To iSuccess
Get ComUpdateString Of hoJson "payment.swiftCode" "" To iSuccess
Get ComUpdateString Of hoJson "payment.terms" "" To iSuccess
Get ComUpdateString Of hoJson "delivery.approach" "" To iSuccess
Get ComUpdateString Of hoJson "delivery.packaging" "" To iSuccess
Get ComUpdateString Of hoJson "delivery.dateValidity" "" To iSuccess
Get ComUpdateString Of hoJson "delivery.exportPort" "" To iSuccess
Get ComUpdateString Of hoJson "delivery.countryOfOrigin" "EG" To iSuccess
Get ComUpdateInt Of hoJson "delivery.grossWeight" 0 To iSuccess
Get ComUpdateInt Of hoJson "delivery.netWeight" 0 To iSuccess
Get ComUpdateString Of hoJson "delivery.terms" "" To iSuccess
Get ComUpdateString Of hoJson "invoiceLines[0].description" "CDM Widget 48GX99X12BA" To iSuccess
Get ComUpdateString Of hoJson "invoiceLines[0].itemType" "GS1" To iSuccess
Get ComUpdateString Of hoJson "invoiceLines[0].itemCode" "7622213335056" To iSuccess
Get ComUpdateString Of hoJson "invoiceLines[0].unitType" "CS" To iSuccess
Get ComUpdateNumber Of hoJson "invoiceLines[0].quantity" "1.00" To iSuccess
Get ComUpdateString Of hoJson "invoiceLines[0].unitValue.currencySold" "EGP" To iSuccess
Get ComUpdateNumber Of hoJson "invoiceLines[0].unitValue.amountEGP" "588.67" To iSuccess
Get ComUpdateInt Of hoJson "invoiceLines[0].unitValue.amountSold" 0 To iSuccess
Get ComUpdateInt Of hoJson "invoiceLines[0].unitValue.currencyExchangeRate" 0 To iSuccess
Get ComUpdateNumber Of hoJson "invoiceLines[0].salesTotal" "588.67" To iSuccess
Get ComUpdateNumber Of hoJson "invoiceLines[0].total" "603.97" To iSuccess
Get ComUpdateInt Of hoJson "invoiceLines[0].valueDifference" 0 To iSuccess
Get ComUpdateInt Of hoJson "invoiceLines[0].totalTaxableFees" 0 To iSuccess
Get ComUpdateNumber Of hoJson "invoiceLines[0].netTotal" "529.8" To iSuccess
Get ComUpdateInt Of hoJson "invoiceLines[0].itemsDiscount" 0 To iSuccess
Get ComUpdateNumber Of hoJson "invoiceLines[0].discount.rate" "10.00" To iSuccess
Get ComUpdateNumber Of hoJson "invoiceLines[0].discount.amount" "58.87" To iSuccess
Get ComUpdateString Of hoJson "invoiceLines[0].taxableItems[0].taxType" "T1" To iSuccess
Get ComUpdateNumber Of hoJson "invoiceLines[0].taxableItems[0].amount" "74.17" To iSuccess
Get ComUpdateString Of hoJson "invoiceLines[0].taxableItems[0].subType" "No sub" To iSuccess
Get ComUpdateNumber Of hoJson "invoiceLines[0].taxableItems[0].rate" "14.00" To iSuccess
Get ComUpdateString Of hoJson "invoiceLines[0].internalCode" "9099994" To iSuccess
Get ComUpdateNumber Of hoJson "totalSales" "588.67" To iSuccess
Get ComUpdateNumber Of hoJson "totalSalesAmount" "588.67" To iSuccess
Get ComUpdateNumber Of hoJson "totalDiscountAmount" "58.87" To iSuccess
Get ComUpdateNumber Of hoJson "netAmount" "529.80" To iSuccess
Get ComUpdateString Of hoJson "taxTotals[0].taxType" "T1" To iSuccess
Get ComUpdateNumber Of hoJson "taxTotals[0].amount" "74.17" To iSuccess
Get ComUpdateInt Of hoJson "extraDiscountAmount" 0 To iSuccess
Get ComUpdateInt Of hoJson "totalItemsDiscountAmount" 0 To iSuccess
Get ComUpdateNumber Of hoJson "totalAmount" "603.97" To iSuccess
Set ComEmitCompact Of hoJson To True
Get ComEmit Of hoJson To sJsonToSign
// Create the CAdES-BES signature.
Set ComEncodingMode Of hoCrypt To "base64"
// Make sure we sign the utf-8 byte representation of the JSON string
Set ComCharset Of hoCrypt To "utf-8"
Get ComSignStringENC Of hoCrypt sJsonToSign To sSigBase64
Get ComLastMethodSuccess Of hoCrypt To bTemp1
If (bTemp1 = False) Begin
Get ComLastErrorText Of hoCrypt To sTemp1
Showln sTemp1
Procedure_Return
End
Showln "Base64 signature:"
Showln sSigBase64
// Insert the base64 signature into the JSON to be sent
Get ComUpdateString Of hoJson "signatures[0].signatureType" "I" To iSuccess
Get ComUpdateString Of hoJson "signatures[0].value" sSigBase64 To iSuccess
// Wrap the JSON in {"documents":[ ... ]}
Get Create (RefClass(cComChilkatStringBuilder)) To hoSbToSend
If (Not(IsComObjectCreated(hoSbToSend))) Begin
Send CreateComObject of hoSbToSend
End
Get ComAppend Of hoSbToSend '{"documents":[' To iSuccess
Get ComEmit Of hoJson To sTemp1
Get ComAppend Of hoSbToSend sTemp1 To iSuccess
Get ComAppend Of hoSbToSend "]}" To iSuccess
// ------------------------------------------------------------------------
// Get an access token using our client ID and client secret key
Move "abc999ff-1234" To sClientId
Move "123fff22-1234-abcd" To sClientSecretKey
Get Create (RefClass(cComChilkatHttp)) To hoHttp
If (Not(IsComObjectCreated(hoHttp))) Begin
Send CreateComObject of hoHttp
End
// Causes the Authorization: Basic header to be added..
Set ComLogin Of hoHttp To sClientId
Set ComPassword Of hoHttp To sClientSecretKey
Set ComBasicAuth Of hoHttp To True
Get Create (RefClass(cComChilkatHttpRequest)) To hoReq
If (Not(IsComObjectCreated(hoReq))) Begin
Send CreateComObject of hoReq
End
Set ComHttpVerb Of hoReq To "POST"
Set ComPath Of hoReq To "/connect/token"
Set ComContentType Of hoReq To "application/x-www-form-urlencoded"
Send ComAddParam To hoReq "grant_type" "client_credentials"
Send ComAddHeader To hoReq "Connection" "close"
Set ComAccept Of hoHttp To "application/json"
Get Create (RefClass(cComChilkatHttpResponse)) To hoResp
If (Not(IsComObjectCreated(hoResp))) Begin
Send CreateComObject of hoResp
End
Get pvComObject of hoReq to vReq
Get pvComObject of hoResp to vResp
Get ComHttpReq Of hoHttp "https://id.preprod.eta.gov.eg/connect/token" vReq vResp To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoHttp To sTemp1
Showln sTemp1
Procedure_Return
End
Get ComCloseAllConnections Of hoHttp To iSuccess
Get ComStatusCode Of hoResp To iTemp1
Showln "Response status code: " iTemp1
Showln "Response body:"
Get ComBodyStr Of hoResp To sTemp1
Showln sTemp1
Get ComStatusCode Of hoResp To iTemp1
If (iTemp1 <> 200) Begin
Showln "Failed."
Procedure_Return
End
Get Create (RefClass(cComChilkatJsonObject)) To hoJsonToken
If (Not(IsComObjectCreated(hoJsonToken))) Begin
Send CreateComObject of hoJsonToken
End
Get ComBodyStr Of hoResp To sTemp1
Get ComLoad Of hoJsonToken sTemp1 To iSuccess
Get ComStringOf Of hoJsonToken "access_token" To sAccessToken
Showln "access_token = " sAccessToken
// ------------------------------------------------------------------------
// Submit the signed JSON to the ETA (Egypt Tax Authority) Portal
// No longer sending basic authentication...
Set ComLogin Of hoHttp To ""
Set ComPassword Of hoHttp To ""
Set ComBasicAuth Of hoHttp To False
// Setting the AuthToken property causes the "Authorization: Bearer <token>" header to be added to each request.
Set ComAuthToken Of hoHttp To sAccessToken
Get ComGetAsString Of hoSbToSend To sJsonStr
Move "https://api.preprod.invoicing.eta.gov.eg/api/v1/documentsubmissions" To sUrl
Get pvComObject of hoResp to vResp
Get ComHttpStr Of hoHttp "POST" sUrl sJsonStr "utf-8" "application/json; charset=utf-8" vResp To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoHttp To sTemp1
Showln sTemp1
Procedure_Return
End
Get ComStatusCode Of hoResp To iTemp1
Showln "Response status code: " iTemp1
Showln "Response body:"
Get ComBodyStr Of hoResp To sTemp1
Showln sTemp1
End_Procedure