Creating Invoices

You can create e-invoices either from spreadsheet data or directly from JSON.

The General Mode of Operation is to first map spreadsheet data to the internal invoice format in JSON and then generate an e-invoice XML or a hybrid PDF/XML file from that JSON. But it is also possible to bypass the first mapping step and generate the invoice directly from JSON data.

Prerequisites

Before you start, you must have:

  • A spreadsheet template. The examples assume that you use the template in contrib/templates/default-invoice.ods.
  • A mapping definition. The examples assume that you use the mapping file in contrib/mappings/default-invoice.yaml.
  • LibreOffice installed on your system (not always necessary).
  • You have started the server. The examples assume that the server is available at http://localhost:3000.
  • You have changed directory to the top-level directory of the repository so that the sample files are available.
  • You have set the necessary environment variables.

E-Invoice-EU uses LibreOffice in headless mode to create PDFs from spreadsheet files. If you do not use this feature, there is no need for LibreOffice. Alternatively, you can always provide a PDF file from other sources instead of generating it from spreadsheet data.

Creating Invoices from Spreadsheet Data

The API endpoint for this functionality is /api/invoice/create/:FORMAT.

Basic E-invoice

In its most simple form, you can create an e-invoice from the spreadsheet data like this:

curl -X POST http://localhost:3000/api/invoice/create/UBL \
    -F data=@contrib/templates/default-invoice.ods \
    -F mapping=@contrib/mappings/default-invoice.yaml
http --form POST http://localhost:3000/api/invoice/create/UBL \
    data@contrib/templates/default-invoice.ods \
    mapping@contrib/mappings/default-invoice.yaml

The format is a path parameter that is specified after the endpoint path api/invoice/create, in this case UBL. The format is case-insensitive.

The invoice data (parameter data) is read from the spreadsheet file contrib/templates/default-invoice.ods. That spreadsheet data is then mapped (parameter mapping) with the mapping definition contrib/mappings/default-invoice.yaml.

E-Invoice with Additional Attachments

It is possible to attach files with additional information. This works both for pure XML formats and for hybrid Factur-X/ZUGFeRD e-invoices. The example creates a Factur-X Extended invoice with two attachments:

curl -X POST \
    http://localhost:3000/api/invoice/create/UBL \
    -F lang=de \
    -F data=@contrib/templates/default-invoice.ods \
    -F mapping=@contrib/mappings/default-invoice.yaml \
    -F embedPDF=1 \
    -F pdf=@invoice.pdf \
    -F pdfID=1234567890 \
    -F pdfDescription="Invoice as PDF." \
    -F "attachment=@time-sheet.ods;type=application/vnd.oasis.opendocument.spreadsheet" \
        -F "attachmentID=abc-123-xyz" \
    -F attachmentDescription="Detailed description of hours spent." \
    -F attachment=@payment-terms.pdf \
    -F attachmentDescription="Our payment terms"
http --form POST http://localhost:3000/api/invoice/create/UBL \
    lang=de \
    data@contrib/templates/default-invoice.ods \
    mapping@contrib/mappings/default-invoice.yaml \
    embedPDF=1 \
    pdf@invoice.pdf \
    pdfID=1234567890 \
    pdfDescription="Invoice as PDF." \
    attachment@time-sheet.ods\;type=application/vnd.oasis.opendocument.spreadsheet \
    attachmentID=abc-123-xyz \
    attachmentDescription="Detailed description of hours spent." \
    attachment@payment-terms.pdf \
    attachmentDescription="Our payment terms"

Let us break that down into the individual URL parameters sent:

  • lang: This is used to determine the language for some canned texts.
  • data: The spreadsheet with the invoice data.
  • mapping: The mapping definition for the invoice data.
  • embedPDF: Embed a PDF version of the e-invoice in the XML; ignored for Factur-X/ZUGFeRD.
  • pdf: The PDF version of the e-invoice. If embedding a PDF was requested but the parameter pdf is missing, the PDF is generated from the spreadsheet file (parameter data).
  • pdfID: The attachment id of the embedded PDF, defaults to the filename.
  • pdfDescription: An optional description of that attachment.
  • attachment: Optionally, an additional file to be embedded.
  • attachmentID: Optionally, the id of the attachment, defaults to the filename.
  • attachmentDescription: An optional description of the attachment.

Each attachment to the e-invoice may have an optional id and an optional description. However, the service only "sees" 3 lists of the URL parameters attachment, attachmentID, and attachmentDescription, even if you group them per attachment.

If you use the parameter attachment four times, attachmentID twice, and attachmentDescription three times, in whatever order, the following attachments are embedded:

Attachment Filename ID Description
Attachment #1 attachment #1 attachmentID #1 attachmentDescription #1
Attachment #2 attachment #2 attachmentID #2 attachmentDescription #2
Attachment #3 attachment #3 - attachmentDescription #3
Attachment #4 attachment #4 - -

You will probably want to avoid that hassle by specifying an id and/or description either for all attachments or for none.

Factur-X/ZUGFeRD Example

There is nothing special about creating Factur-X/ZUGFeRD, only that the output is binary and you want to redirect it to a file.

curl -X POST http://localhost:3000/api/invoice/create/Factur-X-Extended \
    -F data=@contrib/templates/default-invoice.ods \
    -F mapping=@contrib/mappings/default-invoice.yaml >e-invoice.pdf
http --form POST http://localhost:3000/api/invoice/create/Factur-X-Extended \
    data@contrib/templates/default-invoice.ods \
    mapping@contrib/mappings/default-invoice.yaml >e-invoice.pdf

This would create a Factur-X/ZUGFeRD e-invoice with the profile Extended.

You must also keep in mind that the hybrid Factur-X/ZUGFeRD format requires a PDF version of the input. You must either specify it yourself with the parameter pdf or LibreOffice must be available so that it can be generated from the spreadsheet file data.

Creating Invoices from JSON

You can bypass the mapping step and generate the invoice directly from JSON. All you have to do is to omit the parameter mapping.

Example:

curl -X POST http://localhost:3000/api/invoice/create/UBL \
    -F invoice=@contrib/data/default-invoice.json
http --form POST http://localhost:3000/api/invoice/create/UBL \
    invoice@contrib/data/default-invoice.json

In this case, a Peppol UBL invoice is created.

This endpoint allows the exact same URL parameters as the endpoint for creating invoices from spreadsheet data except for the parameter mapping which makes no sense.

Create JSON Data from Spreadsheet Data

You can also create invoice data in the internal format from a spreadsheet file with the endpoint /api/mapping/transform/:format. This is probably only useful for informational purposes because JSON is not an allowed format for e-invoices.

Example:

curl -X POST http://localhost:3000/api/mapping/transform/UBL \
    -F data=@contrib/templates/default-invoice.ods \
    -F mapping=@contrib/mappings/default-invoice.yaml
http --form POST http://localhost:3000/api/mapping/transform/UBL \
    data@contrib/templates/default-invoice.ods \
    mapping@contrib/mappings/default-invoice.yaml

This endpoint only supports two URL parameters:

  • data: The spreadsheet with the invoice data.
  • mapping: The mapping definition for the invoice data.
This website uses cookies and similar technologies to provide certain features, enhance the user experience and deliver content that is relevant to your interests. Depending on their purpose, analysis and marketing cookies may be used in addition to technically necessary cookies. By clicking on "Agree and continue", you declare your consent to the use of the aforementioned cookies. Here you can make detailed settings or revoke your consent (in part if necessary) with effect for the future. For further information, please refer to our Privacy Policy.