[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"docs:faq":3},{"versions":4,"version":26,"nav":28,"path":95,"kind":106,"page":107},[5,10,13,16,18,20,22,24],{"name":6,"label":7,"prefix":8,"channel":9},"0.7","0.7 (latest)","","latest",{"name":11,"label":12,"prefix":11,"channel":11},"next","next (unreleased)",{"name":14,"label":14,"prefix":14,"channel":15},"0.6","old",{"name":17,"label":17,"prefix":17,"channel":15},"0.5",{"name":19,"label":19,"prefix":19,"channel":15},"0.4",{"name":21,"label":21,"prefix":21,"channel":15},"0.3",{"name":23,"label":23,"prefix":23,"channel":15},"0.2",{"name":25,"label":25,"prefix":25,"channel":15},"0.1",{"name":6,"label":7,"prefix":8,"channel":9,"base":27},"\u002Fdocs",[29,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,91,94,97,100,103],{"slug":30,"title":31,"preview":32},"index","Home",false,{"slug":34,"title":35,"preview":32},"getting-started","Getting started",{"slug":37,"title":38,"preview":32},"concepts","E-invoicing basics",{"slug":40,"title":41,"preview":32},"examples","Examples",{"slug":43,"title":44,"preview":32},"building-invoices","Building invoices",{"slug":46,"title":47,"preview":32},"formats","Formats and profiles",{"slug":49,"title":50,"preview":32},"validation","Validation",{"slug":52,"title":53,"preview":32},"templates","Templates and design",{"slug":55,"title":56,"preview":32},"documents","Quotes and other documents",{"slug":58,"title":59,"preview":32},"reading","Reading incoming invoices",{"slug":61,"title":62,"preview":32},"laravel","Laravel integration",{"slug":64,"title":65,"preview":32},"configuration","Configuration",{"slug":67,"title":68,"preview":32},"commands","Artisan commands",{"slug":70,"title":71,"preview":32},"testing","Testing",{"slug":73,"title":74,"preview":32},"country-packs","Country packs",{"slug":76,"title":77,"parent":74,"preview":32},"country-at","Austria",{"slug":79,"title":80,"parent":74,"preview":32},"country-be","Belgium",{"slug":82,"title":83,"parent":74,"preview":32},"country-ch","Switzerland",{"slug":85,"title":86,"parent":74,"preview":32},"country-fr","France",{"slug":88,"title":89,"preview":90},"managed","Managed layer (preview)",true,{"slug":92,"title":93,"preview":32},"troubleshooting","Troubleshooting",{"slug":95,"title":96,"preview":32},"faq","FAQ",{"slug":98,"title":99,"preview":32},"compatibility","Versioning and compatibility",{"slug":101,"title":102,"preview":32},"field-reference","Field reference",{"slug":104,"title":105,"preview":32},"ai","AI assistants","page",{"title":96,"description":108,"html":109,"headings":110,"editUrl":133,"markdownUrl":134,"prev":135,"next":136},"Short answers to questions that come up before and after the first invoice, with links to the pages that explain the details. For error messages, see Troubleshooting.","\u003Ch1 id=\"faq\">FAQ\u003C\u002Fh1>\n\u003Cp>Short answers to questions that come up before and after the first invoice, with links to the pages that explain the details. For error messages, see \u003Ca href=\"\u002Fdocs\u002Ftroubleshooting\">Troubleshooting\u003C\u002Fa>.\u003C\u002Fp>\n\u003Ch2 id=\"does-quittio-send-invoices\">Does Quittio send invoices?\u003Ca class=\"q-doc-anchor\" href=\"#does-quittio-send-invoices\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>No. Quittio creates, validates, reads and renders invoices; how they reach the buyer is up to your application:\u003C\u002Fp>\n\u003Cul>\n\u003Cli>\u003Cstrong>E-mail:\u003C\u002Fstrong> attach the result to a mailable; \u003Ccode>RenderedInvoice\u003C\u002Fcode> implements Laravel's \u003Ccode>Attachable\u003C\u002Fcode> (\u003Ca href=\"\u002Fdocs\u002Flaravel\">Laravel integration\u003C\u002Fa>).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Peppol:\u003C\u002Fstrong> the format \u003Ccode>peppol\u003C\u002Fcode> writes UBL according to Peppol BIS Billing 3.0. Sending it needs a Peppol access point, a service provider connected to the network; hand it the XML from \u003Ccode>$result-&gt;xml()\u003C\u002Fcode> (\u003Ca href=\"\u002Fdocs\u002Fformats#peppol-bis-billing-30\">Peppol BIS Billing 3.0\u003C\u002Fa>). A Peppol lookup lets the automatic choice pick \u003Ccode>peppol\u003C\u002Fcode> for buyers that are reachable there (\u003Ca href=\"\u002Fdocs\u002Fformats#peppol-lookup\">Peppol lookup\u003C\u002Fa>).\u003C\u002Fli>\n\u003Cli>\u003Cstrong>Public buyers in Germany:\u003C\u002Fstrong> upload the XRechnung to the portal the authority names, or send it via Peppol (\u003Ca href=\"\u002Fdocs\u002Fexamples#public-sector\">Examples: Public sector\u003C\u002Fa>).\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Ch2 id=\"which-format-meets-the-german-e-invoicing-obligation\">Which format meets the German e-invoicing obligation?\u003Ca class=\"q-doc-anchor\" href=\"#which-format-meets-the-german-e-invoicing-obligation\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Since 1 January 2025 every business in Germany must be able to receive e-invoices. Sending them becomes mandatory step by step: the transitional rules of section 27 (38) UStG still allow other invoices for domestic business-to-business supplies until the end of 2026, and in 2027 for businesses whose total turnover of the previous year was at most 800,000 euros. From 2028 domestic business invoices must be e-invoices. Invoices to consumers and small amount invoices up to 250 euros are not affected (\u003Ca href=\"\u002Fdocs\u002Fconcepts\">E-invoicing basics\u003C\u002Fa>).\u003C\u002Fp>\n\u003Cp>An e-invoice in this sense is a structured format that conforms to EN 16931. With Quittio these are:\u003C\u002Fp>\n\u003Ctable class=\"q-doc-table q-stack-table\">\n\u003Cthead>\n\u003Ctr>\n\u003Cth>Format\u003C\u002Fth>\n\u003Cth>Profile\u003C\u002Fth>\n\u003C\u002Ftr>\n\u003C\u002Fthead>\n\u003Ctbody>\n\u003Ctr>\n\u003Ctd>\u003Ccode>zugferd\u003C\u002Fcode> \u002F \u003Ccode>factur-x\u003C\u002Fcode> (PDF with embedded XML)\u003C\u002Ftd>\n\u003Ctd data-label=\"Profile\">\u003Ccode>en16931\u003C\u002Fcode> (the default) or \u003Ccode>extended\u003C\u002Fcode>; not \u003Ccode>minimum\u003C\u002Fcode> or \u003Ccode>basic-wl\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>xrechnung-cii\u003C\u002Fcode>, \u003Ccode>xrechnung-ubl\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Profile\">\u003Ccode>xrechnung\u003C\u002Fcode> (required for public buyers)\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>cii\u003C\u002Fcode>, \u003Ccode>ubl\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Profile\">\u003Ccode>en16931\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003Ctr>\n\u003Ctd>\u003Ccode>peppol\u003C\u002Fcode>\u003C\u002Ftd>\n\u003Ctd data-label=\"Profile\">\u003Ccode>peppol\u003C\u002Fcode>\u003C\u002Ftd>\n\u003C\u002Ftr>\n\u003C\u002Ftbody>\n\u003C\u002Ftable>\n\u003Cp>A plain \u003Ccode>pdf\u003C\u002Fcode> is no e-invoice. MINIMUM and BASIC WL carry no lines and do not conform to EN 16931; the validation warns with \u003Ccode>QUITTIO-PROFILE-NOT-EINVOICE\u003C\u002Fcode>. The German country pack chooses \u003Ccode>zugferd\u003C\u002Fcode> for domestic business invoices, XRechnung for public buyers and \u003Ccode>pdf\u003C\u002Fcode> for consumers and small amount invoices (\u003Ca href=\"\u002Fdocs\u002Fcountry-packs#format-choice\">German format choice\u003C\u002Fa>). If you choose another format yourself, it checks the obligation by the supply date: a warning during the transition (\u003Ccode>DE-EINVOICE-02\u003C\u002Fcode>), an error once an e-invoice is required (\u003Ccode>DE-EINVOICE-01\u003C\u002Fcode>, \u003Ca href=\"\u002Fdocs\u002Fcountry-packs#e-invoice-obligation\">E-invoice obligation\u003C\u002Fa>).\u003C\u002Fp>\n\u003Cp>This is a summary, not legal advice. The legal wording of the country pack was reviewed by a tax adviser in October 2026; see the legal review and the disclaimer in the README of the repository.\u003C\u002Fp>\n\u003Ch2 id=\"do-i-need-java\">Do I need Java?\u003Ca class=\"q-doc-anchor\" href=\"#do-i-need-java\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Only for the official Schematron check (validation level L5) with the KoSIT validator, which runs on Java. Building, calculating, validating levels L1 to L4 and L7, writing XML, rendering PDF\u002FA and reading invoices are pure PHP.\u003C\u002Fp>\n\u003Cp>The KoSIT validator can run as a daemon in another container or on another host, so the PHP application itself does not need Java (\u003Ca href=\"\u002Fdocs\u002Fvalidation#kosit-validator-l5\">KoSIT validator\u003C\u002Fa>). The PDF\u002FA check (L6) uses veraPDF, locally or through Docker. Both are off by default.\u003C\u002Fp>\n\u003Ch2 id=\"which-exceptions-does-reading-throw\">Which exceptions does reading throw?\u003Ca class=\"q-doc-anchor\" href=\"#which-exceptions-does-reading-throw\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>Reading throws only when the file cannot be read as an invoice at all: \u003Ccode>UnsafeXmlException\u003C\u002Fcode> (too large, not well-formed, DOCTYPE, limits), \u003Ccode>PdfException\u003C\u002Fcode> (encrypted, malformed or too large PDF) and \u003Ccode>UnreadableInvoiceException\u003C\u002Fcode> (unknown format, ZUGFeRD 1.0, a PDF without embedded invoice, a missing file). All three implement \u003Ccode>Quittio\\Core\\Exceptions\\QuittioException\u003C\u002Fcode>. Everything else, for example totals that differ from a recalculation, becomes a finding of the result (\u003Ca href=\"\u002Fdocs\u002Freading#errors\">Reading: Errors\u003C\u002Fa>).\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>php\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Core\\Exceptions\\QuittioException\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">use\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\\Laravel\\Facades\\Quittio\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FF7B72\">try\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#E6EDF3\">    $read \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> Quittio\u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">::\u003C\u002Fspan>\u003Cspan style=\"color:#D2A8FF\">readFile\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\">($path);\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">} \u003C\u002Fspan>\u003Cspan style=\"color:#FF7B72\">catch\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> (\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\">QuittioException\u003C\u002Fspan>\u003Cspan style=\"color:#E6EDF3\"> $e) {\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:6ch;text-indent:-6ch\">\u003Cspan style=\"color:#8B949E\">    \u002F\u002F not an invoice Quittio can read: reject the upload\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#E6EDF3\">}\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Ch2 id=\"where-does-mpdf-write-temporary-files\">Where does mPDF write temporary files?\u003Ca class=\"q-doc-anchor\" href=\"#where-does-mpdf-write-temporary-files\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>mPDF needs a writable temporary directory for fonts and images; Quittio also caches prepared logos in its \u003Ccode>logos\u003C\u002Fcode> subdirectory. In Laravel it is \u003Ccode>pdf.cache_path\u003C\u002Fcode> (default \u003Ccode>storage\u002Fframework\u002Fcache\u002Fquittio\u003C\u002Fcode>), without Laravel \u003Ccode>temp_dir\u003C\u002Fcode> of the configuration (default \u003Ccode>sys_get_temp_dir()\u002Fquittio-mpdf\u003C\u002Fcode>). On read-only file systems and in containers, point it to a writable volume (\u003Ca href=\"\u002Fdocs\u002Fconfiguration\">Configuration\u003C\u002Fa>).\u003C\u002Fp>\n\u003Ch2 id=\"how-much-time-and-memory-does-rendering-take\">How much time and memory does rendering take?\u003Ca class=\"q-doc-anchor\" href=\"#how-much-time-and-memory-does-rendering-take\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>It depends on the template, the number of lines and pages, logos and fonts. Measure it on your server with the sample invoices:\u003C\u002Fp>\n\u003Cdiv class=\"q-doc-code\">\u003Cdiv class=\"q-doc-code-bar\">\u003Cspan>bash\u003C\u002Fspan>\u003Cbutton type=\"button\" class=\"q-doc-copy\" data-copy aria-label=\"Copy code\">\u003Csvg xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\u003Crect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\"\u002F>\u003Cpath d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"\u002F>\u003C\u002Fsvg>\u003Cspan>Copy\u003C\u002Fspan>\u003C\u002Fbutton>\u003C\u002Fdiv>\u003Cpre class=\"shiki github-dark-default\" style=\"background-color:#0d1117;color:#e6edf3\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\" style=\"padding-left:2ch;text-indent:-2ch\">\u003Cspan style=\"color:#FFA657\">php\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> artisan\u003C\u002Fspan>\u003Cspan style=\"color:#A5D6FF\"> quittio:benchmark\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --scenario=many-lines\u003C\u002Fspan>\u003Cspan style=\"color:#79C0FF\"> --count=20\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\u003C\u002Fdiv>\n\u003Cp>The command prints the average, minimum, 95th percentile and maximum time and the peak memory (\u003Ca href=\"\u002Fdocs\u002Fcommands\">Artisan commands\u003C\u002Fa>). Invoices over several pages take longer, because the line table is laid out again for the carry-over at each page break. For many invoices at once, render in the queue.\u003C\u002Fp>\n\u003Ch2 id=\"what-happens-to-queued-invoices-after-an-update\">What happens to queued invoices after an update?\u003Ca class=\"q-doc-anchor\" href=\"#what-happens-to-queued-invoices-after-an-update\" aria-label=\"Link to this section\">#\u003C\u002Fa>\u003C\u002Fh2>\n\u003Cp>A queued render (\u003Ccode>-&gt;queue()-&gt;save()\u003C\u002Fcode>) stores the invoice as a versioned JSON snapshot and the render options as versioned JSON, not as PHP objects. When the data model changes between the dispatch and the run of the job, the configured upcasters bring the snapshot up to date (\u003Ccode>quittio.snapshots.upcasters\u003C\u002Fcode>), so the job renders the current model (\u003Ca href=\"\u002Fdocs\u002Flaravel#queueing\">Queueing\u003C\u002Fa>, \u003Ca href=\"\u002Fdocs\u002Fconfiguration#snapshots\">Snapshots\u003C\u002Fa>). Queued documents (\u003Ccode>Quittio::document($quote)-&gt;queue()-&gt;save()\u003C\u002Fcode>) work the same way with their own snapshot version and \u003Ccode>quittio.snapshots.document_upcasters\u003C\u002Fcode> (\u003Ca href=\"\u002Fdocs\u002Fdocuments#queueing\">Documents: queueing\u003C\u002Fa>). Let the queue run empty before an update anyway, as for any job whose code changes.\u003C\u002Fp>\n",[111,115,118,121,124,127,130],{"id":112,"text":113,"level":114},"does-quittio-send-invoices","Does Quittio send invoices?",2,{"id":116,"text":117,"level":114},"which-format-meets-the-german-e-invoicing-obligation","Which format meets the German e-invoicing obligation?",{"id":119,"text":120,"level":114},"do-i-need-java","Do I need Java?",{"id":122,"text":123,"level":114},"which-exceptions-does-reading-throw","Which exceptions does reading throw?",{"id":125,"text":126,"level":114},"where-does-mpdf-write-temporary-files","Where does mPDF write temporary files?",{"id":128,"text":129,"level":114},"how-much-time-and-memory-does-rendering-take","How much time and memory does rendering take?",{"id":131,"text":132,"level":114},"what-happens-to-queued-invoices-after-an-update","What happens to queued invoices after an update?","https:\u002F\u002Fgithub.com\u002FQuittio\u002Fquittio\u002Fedit\u002Fmaster\u002Fdocs\u002Ffaq.md","\u002Fdocs\u002Ffaq.md",{"slug":92,"title":93},{"slug":98,"title":99}]