![]() |
Chilkat HOME Android™ AutoIt C C# C++ Chilkat2-Python CkPython Classic ASP DataFlex Delphi DLL Go Java Node.js Objective-C PHP Extension Perl PowerBuilder PowerShell PureBasic Ruby SQL Server Swift Tcl Unicode C Unicode C++ VB.NET VBScript Visual Basic 6.0 Visual FoxPro Xojo Plugin
(PureBasic) Create Signed SOAP XML for Albanian Fiscalization ServiceThis example is created for a customer that needs to send signed billing/invoicing SOAP XML requests to http://efiskalizimi-test.tatime.gov.al:80/FiscalizationService The example demonstrates how to create and signed the SOAP XML message that is to be sent. Note: This example requires Chilkat v11.0.0 or greater.
IncludeFile "CkXml.pb" IncludeFile "CkHttp.pb" IncludeFile "CkXmlDSigGen.pb" IncludeFile "CkStringBuilder.pb" IncludeFile "CkHttpResponse.pb" IncludeFile "CkCert.pb" Procedure ChilkatExample() success.i = 0 ; This example assumes the Chilkat API to have been previously unlocked. ; See Global Unlock Sample for sample code. ; -------------------------------------------------------------------------------- ; Also see Chilkat's Online WSDL Code Generator ; to generate code and SOAP Request and Response XML for each operation in a WSDL. ; -------------------------------------------------------------------------------- ; We want to build and send a signed SOAP XML that looks like the following: ; ; <?xml version="1.0" encoding="utf-8"?> ; <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> ; <SOAP-ENV:Header/> ; <SOAP-ENV:Body> ; <RegisterWTNRequest xmlns="https://eFiskalizimi.tatime.gov.al/FiscalizationService/schema" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" Id="Request"> ; <Header SendDateTime="2019-09-03T14:19:01+02:00" UUID="42db3af5-0d9f-4dea-95b4-4b947ab8d8e7"/> ; <WTN BusinUnit="bb123bb123" DateTimeCreated="2019-09-03T14:19:01+02:00" DestinAddr="Destination address" ; DestinCity="Destination city" IsAfterDel="false" OperatorCode="oo123oo123" ; SoftNum="ss123ss123" StartAddr="Start address" StartCity="Start city" TransDate="2019-09-03T14:19:01+02:00" ; VehPlates="AA0000AA" WTNIC="5C5E58580D0A24E1F7A5E5E011929511" WTNICSignature="82D69C38206D ... F5FCA48" WTNNum="12345678901"> ; <Issuer NUIS="I12345678I" Name="Issuer name"/> ; <Items> ; <I C="501234567890" N="Item name" Q="1.0" U="piece"/> ; </Items> ; </WTN> ; <Signature xmlns="http://www.w3.org/2000/09/xmldsig#"> ; <SignedInfo> ; <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> ; <SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/> ; <Reference URI="#Request"> ; <Transforms> ; <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/> ; <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/> ; </Transforms> ; <DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/> ; <DigestValue>aNa0r4RW04BlsAciTUrWHGW9PADskl2op315BAQ0hTg=</DigestValue> ; </Reference> ; </SignedInfo> ; <SignatureValue>4/j/d4j/5xCJ2YUP+XTC6li0B94...........................KESd38NT5+puArBcNgLYIjLx/dh6Q==</SignatureValue> ; <KeyInfo> ; <X509Data> ; <X509Certificate>MIIE6TCCAtGgAwIBAgICEA8wDQYJKoZIhvcNA......................uoqWsSuLmA==</X509Certificate> ; </X509Data> ; </KeyInfo> ; </Signature> ; </RegisterWTNRequest> ; </SOAP-ENV:Body> ; </SOAP-ENV:Envelope> success = 1 ; Create the XML to be signed... xmlToSign.i = CkXml::ckCreate() If xmlToSign.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXml::setCkTag(xmlToSign, "SOAP-ENV:Envelope") CkXml::ckAddAttribute(xmlToSign,"xmlns:SOAP-ENV","http://schemas.xmlsoap.org/soap/envelope/") CkXml::ckUpdateChildContent(xmlToSign,"SOAP-ENV:Header","") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest",1,"xmlns","https://eFiskalizimi.tatime.gov.al/FiscalizationService/schema") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest",1,"xmlns:ns2","http://www.w3.org/2000/09/xmldsig#") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest",1,"Id","Request") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|Header",1,"SendDateTime","2019-09-03T14:19:01+02:00") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|Header",1,"UUID","42db3af5-0d9f-4dea-95b4-4b947ab8d8e7") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"BusinUnit","bb123bb123") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"DateTimeCreated","2019-09-03T14:19:01+02:00") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"DestinAddr","Destination address") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"DestinCity","Destination city") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"IsAfterDel","false") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"OperatorCode","oo123oo123") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"SoftNum","ss123ss123") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"StartAddr","Start address") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"StartCity","Start city") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"TransDate","2019-09-03T14:19:01+02:00") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"VehPlates","AA0000AA") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"WTNIC","5C5E58580D0A24E1F7A5E5E011929511") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"WTNICSignature","82D69C38206D ... F5FCA48") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN",1,"WTNNum","12345678901") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN|Issuer",1,"NUIS","I12345678I") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN|Issuer",1,"Name","Issuer name") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN|Items|I",1,"C","501234567890") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN|Items|I",1,"N","Item name") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN|Items|I",1,"Q","1.0") CkXml::ckUpdateAttrAt(xmlToSign,"SOAP-ENV:Body|RegisterWTNRequest|WTN|Items|I",1,"U","piece") gen.i = CkXmlDSigGen::ckCreate() If gen.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXmlDSigGen::setCkSigLocation(gen, "SOAP-ENV:Envelope|SOAP-ENV:Body|RegisterWTNRequest") CkXmlDSigGen::setCkSigLocationMod(gen, 0) CkXmlDSigGen::setCkSigNamespacePrefix(gen, "") CkXmlDSigGen::setCkSigNamespaceUri(gen, "http://www.w3.org/2000/09/xmldsig#") CkXmlDSigGen::setCkSignedInfoCanonAlg(gen, "EXCL_C14N") CkXmlDSigGen::setCkSignedInfoDigestMethod(gen, "sha256") ; -------- Reference 1 -------- CkXmlDSigGen::ckAddSameDocRef(gen,"Request","sha256","EXCL_C14N","","") ; Provide a certificate + private key. (PFX password is test123) cert.i = CkCert::ckCreate() If cert.i = 0 Debug "Failed to create object." ProcedureReturn EndIf success = CkCert::ckLoadPfxFile(cert,"qa_data/pfx/cert_test123.pfx","test123") If success = 0 Debug CkCert::ckLastErrorText(cert) CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkCert::ckDispose(cert) ProcedureReturn EndIf CkXmlDSigGen::ckSetX509Cert(gen,cert,1) CkXmlDSigGen::setCkKeyInfoType(gen, "X509Data") CkXmlDSigGen::setCkX509Type(gen, "Certificate") ; Load XML to be signed... sbXml.i = CkStringBuilder::ckCreate() If sbXml.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXml::ckGetXmlSb(xmlToSign,sbXml) CkXmlDSigGen::setCkBehaviors(gen, "CompactSignedXml,ForceAddEnvelopedSignatureTransform") ; Sign the XML... success = CkXmlDSigGen::ckCreateXmlDSigSb(gen,sbXml) If success = 0 Debug CkXmlDSigGen::ckLastErrorText(gen) CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkCert::ckDispose(cert) CkStringBuilder::ckDispose(sbXml) ProcedureReturn EndIf ; ----------------------------------------------- ; Now to send the SOAP request.... ; Note: Chilkat did not actually test this by sending the request to the server. ; The example is a best-guess for how to do it... strXml.s = CkStringBuilder::ckGetAsString(sbXml) responseStatusCode.i ; We'll need to add this in the HTTP header: ; SOAPAction: "https://eFiskalizimi.tatime.gov.al/FiscalizationService/RegisterWTN" ; Note: This is for the RegisterWTN request. ; You may wish to load the WSDL at https://efiskalizimi-test.tatime.gov.al/FiscalizationService-v1/FiscalizationService.wsdl into the SoapUI application to see ; the SOAP requests.. http.i = CkHttp::ckCreate() If http.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkHttp::ckSetRequestHeader(http,"SOAPAction","https://eFiskalizimi.tatime.gov.al/FiscalizationService/RegisterWTN") ; The testing endpoint for this soap service is likely: endPoint.s = "https://efiskalizimi-test.tatime.gov.al/FiscalizationService-v1" resp.i = CkHttpResponse::ckCreate() If resp.i = 0 Debug "Failed to create object." ProcedureReturn EndIf success = CkHttp::ckHttpStr(http,"POST",endPoint,strXml,"utf-8","text/xml",resp) If success = 0 Debug CkHttp::ckLastErrorText(http) CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkCert::ckDispose(cert) CkStringBuilder::ckDispose(sbXml) CkHttp::ckDispose(http) CkHttpResponse::ckDispose(resp) ProcedureReturn EndIf responseStatusCode = CkHttpResponse::ckStatusCode(resp) ; Check that the responseStatusCode equals 200... Debug "Response Status Code: " + Str(responseStatusCode) ; Examine the exact HTTP header sent with the POST like this: Debug "LastHeader:" Debug CkHttp::ckLastHeader(http) ; Examine the XML returned by the web service: Debug "XML Response:" xmlResp.i = CkXml::ckCreate() If xmlResp.i = 0 Debug "Failed to create object." ProcedureReturn EndIf CkXml::ckLoadXml(xmlResp,CkHttpResponse::ckBodyStr(resp)) Debug CkXml::ckGetXml(xmlResp) ; Use this online tool to generate parsing code from response XML: ; Generate Parsing Code from XML CkXml::ckDispose(xmlToSign) CkXmlDSigGen::ckDispose(gen) CkCert::ckDispose(cert) CkStringBuilder::ckDispose(sbXml) CkHttp::ckDispose(http) CkHttpResponse::ckDispose(resp) CkXml::ckDispose(xmlResp) ProcedureReturn EndProcedure |
© 2000-2025 Chilkat Software, Inc. All Rights Reserved.