Add an Encoded Attachment to a cXML Invoice
Overview
You can transmit invoice attachments as part of the invoice cXML using Base64 multipart. You'll need to build your own script that takes three inputs and encodes the attachments and image scans (but not cXML) in Base64 multipart format. Your script will also need to create a random boundary, shown in the example encoded invoice, below. It also needs to include Content-Type
and Content-ID
for each file.
Script inputs
In order to generate a cXML Invoice with attachments encoded in it, you need to create a script that takes specific inputs and generates a cXML invoice with the encoded attachments.
Make sure that your regular cXML Invoice file includes the following elements for attachments and the extrinsic image scan:
<Comments> <Attachment> <URL>https://www.google.com/images/srpr/logo11w.png</URL> //If your attachment is publicly accessible by a URL, specify the URL. </Attachment> <Attachment> <URL>cid:test.pdf</URL> //If we have the attachment locally, then specify the content-ID in URL. </Attachment> </Comments> <Extrinsic name="ImageScanAttachmentUrl">cid:test.csv</Extrinsic> //Specify ImageScans with the content-ID.
Script ouptut
Your script should save the output to a file so you can POST it to your customer's instance using curl.
curl -X POST -H 'Accept: application/xml' -H 'Content-Type: multipart/related; boundary=<boundary_value_that_you_have>; type=text/xml; start=<cXML_Invoice_content_id>' --data-binary @<output_file_name>.xml https://<customer_name>.coupahost.com/cxml/invoices
Once the output file is generated, DO NOT OPEN it. Without opening it just POST it to the customer instance. Opening the output file then POSTing it will result in 502 Bad Gateway error.
Example encoded invoice
--ec6xAZMGCwZhdyY0 //Random Boundary Content-type: text/xml; charset=UTF-8 //Content type Content-ID: <payload.xml> //content ID for cXML Invoice file <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.2.020/InvoiceDetail.dtd"> <cXML version="1.2.020" xml:lang="en-US" timestamp="2018-03-08T13:08:23-08:00" payloadID="2018-03-08T13:08:23-08:00"> <Header> <From> <Credential domain="dwqsdg"> <Identity>vcbv</Identity> </Credential> </From> <To> <Credential domain="vfdfvb"> <Identity>dbfg</Identity> </Credential> </To> <Sender> <Credential domain="dwqsdg"> <Identity>vcbv</Identity> <SharedSecret>fdbgfg</SharedSecret> </Credential> <UserAgent>Coupa Procurement 1.0</UserAgent> </Sender> </Header> <Request deploymentMode="production"> <InvoiceDetailRequest> <InvoiceDetailRequestHeader invoiceDate="2018-03-08T13:08:23-08:00" operation="new" purpose="standard" invoiceOrigin="supplier" invoiceID="COUPATEST21"> <InvoiceDetailHeaderIndicator /> <InvoiceDetailLineIndicator isAccountingInLine="yes" /> <PaymentTerm payInNumberOfDays="30" /> //Lines 35-43 are for Attachments //Use filenames as content-IDs so it's easy to recognizing which content-ID refers to which encoded format <Comments> <Attachment> <URL>https://www.google.com/images/srpr/logo11w.png</URL> </Attachment> <Attachment> <URL>cid:test.pdf</URL> </Attachment> </Comments> <Extrinsic name="ImageScanAttachmentUrl">cid:test.csv</Extrinsic> </InvoiceDetailRequestHeader> <InvoiceDetailOrder> <InvoiceDetailOrderInfo> <OrderReference> <DocumentReference payloadID="2820" /> </OrderReference> </InvoiceDetailOrderInfo> <InvoiceDetailItem quantity="1.0" invoiceLineNumber="1"> <UnitOfMeasure>EA</UnitOfMeasure> <UnitPrice> <Money currency="USD">23.34</Money> </UnitPrice> <InvoiceDetailItemReference lineNumber="1"> <ItemID> <SupplierPartID /> <SupplierPartAuxiliaryID /> </ItemID> <Description xml:lang="en-US">test items s</Description> </InvoiceDetailItemReference> <SubtotalAmount> <Money currency="USD">23.34</Money> </SubtotalAmount> </InvoiceDetailItem> </InvoiceDetailOrder> <InvoiceDetailSummary> <SubtotalAmount> <Money currency="USD">23.34</Money> </SubtotalAmount> <Tax> <Money currency="USD">0</Money> <Description xml:lang="en-US" /> <TaxDetail purpose="tax" category="USD" percentageRate="0" taxPointDate="2018-03-08T13:08:23-08:00"> <TaxableAmount> <Money currency="USD">23.34</Money> </TaxableAmount> <TaxAmount> <Money currency="USD">0</Money> </TaxAmount> <TaxLocation xml:lang="en">USD</TaxLocation> </TaxDetail> </Tax> <NetAmount> <Money currency="USD">23.34</Money> </NetAmount> </InvoiceDetailSummary> </InvoiceDetailRequest> </Request> </cXML> --ec6xAZMGCwZhdyY0 //Boundary is displayed as the cXML Invoice ends here Content-Type: text/plain; charset=utf-8 //This content-type refers the test in file Content-Disposition: inline; filename="test.pdf" //Specify the filename and content-disposition remains smae Content-Transfer-Encoding: base64 //input is encoded in base64 foramt Content-ID: <test.pdf> //which file is encoded below //Base64 multipart encoding starts here ... JVBERi0xLjMKJcTl8uXrp/Og0MTGCjQgMCBvYmoKPDwgL0xlbmd0aCA1IDAg UiAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PgpzdHJlYW0KeAHlnGuPJbdxhr/3 r+gYWO+ZxNvb94u/SSsntmzBEjxOsIgNYz0z8trZ0UozUja+6L/7KRZZTZ6+ ... --ec6xAZMGCwZhdyY0 //boundary is displayed as above input of file is completed Content-Type: text/plain; charset=utf-8 //This content-type refers the text/details in file Content-Disposition: inline; filename="test.csv" //Specify the filename and content-disposition remains same Content-Transfer-Encoding: base64 //input is encoded in base64 foramt Content-ID: <test.csv> //which file's is encoded below ... CjAwMDAxOTQ0MjkgMDAwMDAgbiAKMDAwMDE5NDk1NiAwMDAwMCBuIAowMDAw MTk1MjE4IDAwMDAwIG4gCjAwMDAyMjAyMTQgMDAwMDAgbiAKMDAwMDIyMDY4 NyAwMDAwMCBuIAowMDAwMjIwOTU2IDAwMDAwIG4gCjAwMDAyMzc3OTYgMDAw ... --ec6xAZMGCwZhdyY0-- //Base64 multipart encoding ends here