Malaysia E-Invoicing (MyInvois) User Questions Answered

(Questions paraphrased and published here with prior permission from the user.)

Question 1

Our application is file-server based which can be accessed by multiple users over LAN. Quite likely, there will be multiple users and/or applications submitting their e-invoices. Can one certificate file be shared and used by multiple applications? What are the differences between the two certificate types and which example below applies to my situation?
HTTP TLS Mutual Authentication (Client-Side Certificate)
https://www.example-code.com/foxpro/http_tlsMutualAuthentication.asp
Use Installed Cert on Windows for TLS Client Authentication
https://www.example-code.com/foxpro/http_windows_tls_client_cert.asp

Answer 1

The difference in the above examples is only in the source location of the client certificate.  In one example, it is obtained from a .pfx file.  In the other example it is obtained form the certificate (+ private key) that was installed onto a Windows system (in the Windows registry and protected store).  Chilkat provides many ways to use a certificate + private key, such as from various file formats, pre-installed certs (on Windows), or from smart cards and USB tokens.  Regardless of how the Chilkat certificate object was loaded, it’s simply a matter of calling Http.SetSslClientCert(cert) to use the cert for TLS mutual authentication.  (Of course, the certificate must have come from a source, such as a .pfx, where the corresponding private key was also present.)
“Can one certificate file be shared and used by multiple applications?” — I would imagine that each MyInvois account has its own associated certificate, unless perhaps the API calls are made with credentials from “Login as Intermediary System”, where the caller is acting on behalf of a specific taxpayer.

Question 2

I can only superficially understand the example “Create XAdES for Malaysia E-Invoice”: https://www.example-code.com/foxpro/xades_malaysia_eInvoice.asp
Do you mind briefly explaining the important steps in the example, or any hidden knowledge I need to know, any portion of code I need to customize?
I think this example is to read an unsigned XML file, which contains the document data generated by the user  and convert it to a signed XML file.

Answer 2

It’s reasonable to only superficially understand the example.  XML Digital Signatures are ridiculously complicated, and it’s unreasonable for any government to expect application developers at businesses to be able to directly implement XmlDSig as described here:  https://sdk.myinvois.hasil.gov.my/signature-creation/

Chilkat wishes to provide a solution with as much complexity hidden as possible.  Even with this intention, there are many options that need to be set to achieve the specific signed XML that is required by a given authority.  Chilkat’s solution is to provide an online tool that will analyze a given already-signed XML to produce the source code with the required settings/options that would sign the original document to produce the given signed XML.  In other words, if the authority can provide an example of a valid signed XML, such as the one at https://sdk.myinvois.hasil.gov.my/files/one-doc-signed.xml , then it can be input to Chilkat’s online tool to generate the necessary code to produce the signed XML.

Once you have the generated code, you can modify in a few ways.  Perhaps your original document to be signed is different.   Your application code can load the original XML from a file, or you can generate the original (to-be-signed) XML directly from code.  If you wish to generate XML from code, you can use Chilkat’s online XML code generator at https://tools.chilkat.io/xmlCreate

If the XML you are signing is different than the sample from which you generated XML signing code, then it’s important to review the 2 lines of code that specify the location within the original XML for where the XML Signature is to be inserted:

loGen.SigLocation = "Invoice|ext:UBLExtensions|ext:UBLExtension|ext:ExtensionContent|sig:UBLDocumentSignatures|sac:SignatureInformation"
loGen.SigLocationMod = 0

You can read about SigLocation and SigLocationMod  in Chilkat’s online reference documentation at https://www.chilkatsoft.com/refdoc/xChilkatXmlDSigGenRef.html#prop16.  Also ready about Chilkat XML Paths in the Chilkat XML API’s reference documentation  at https://www.chilkatsoft.com/refdoc/xChilkatXmlRef.html#method13

In general, you’ll want to sign the XML, then the signed XML would be contained in the body of a POST to the MyInvois server.  It’s extremely important to not change anything in the signed XML.  The exact bytes of the signed XML, including whitespace and formatting, must be sent in the HTTPS POST to the MyInvois server.  This means you should never load signed XML into a Chilkat XML object which might re-emit the XML with different indentation.

Also, the MyInvois API HTTP  documentation is extremely lacking in that it fails to provide the specifics needed to understand the structure and format of the HTTP requests.  We’re left guessing about where information must be located.  In the HTTP headers?  In query params?  What is the Content-Type?  What is the endpoint? What is the HTTP verb?  Is it a multipart HTTP request?  We simply don’t know.  MyInvois has provided hundreds of pages of documentation, but omits all of necessary specific information a developer would need to know in order to send a properly structured HTTP request to the server (containing the signed XML).

In the same way that MyInvois provide a sample signed XML, all unknowns regarding the HTTP REST API methods would be resolved by providing sample raw HTTP requests and responses.  (I wish all governments would provide this kind of information.  After all, they are requiring taxpayers to implement a system by a certain date, so please make it possible to implement the system.)

Question 3

At the moment, I don’t even know how to generate the unsigned XML. How can I be sure the XML file I generate is what they want?

Answer 3

Use Chilkat’s online XML code generator at https://tools.chilkat.io/xmlCreate

Question 4

Once you have got the XML signed what code is required to submit it?

Answer 4

Again, we are frustrated that governments fail to provide sample raw HTTP requests and responses.  A picture is worth a 1000 words, and just seeing a sample raw HTTP request and response for each REST API call would unambiguously answer all questions.  Instead we are left guessing.

Another developer provided a Postman collection of MyInvois REST API calls, but I’m not so sure they are correct.

Chilkat has an online tool to covert a Postman collection to source code.  The code generator for the MyInvois postman collection is available at https://tools.chilkat.io/PostmanCollection/csharp/start   Look for the “Malaysia MyInvois SDK” button.

Another option for documenting a REST API is to provide a Postman collection that implements each API method.  This is just as good as providing raw HTTP request/response samples.

Question 5

We are currently using the sandbox environment which does not need the digital certificate ( I think ). How do I still able to submit document?

Answer 5

Your application’s source code would be the same, except you don’t need too call Http.SetSslClientCert.

Question 6

Is there any speed issue if we use XML instead of JSON to submit?

Answer 6

No.   But in addition, I’m not aware of any official standard for signed JSON in the same way that the XML DSig standard exists for signed XML.   I’m not sure why there is an attempt to send in JSON format when no solid standard exists.  I would recommend using the XML option.  (I understand that JSON, in general, is more palatable than XML, but it’s not wise to rely on some ad-hoc “standard” for this kind of thing..)  Perhaps I am unaware of something new, but this is my current opinion.