Shopify Invoice Template Generator

A VAT/GST-ready Order Printer invoice template in A4, Letter or 4×6, with an optional tax breakdown.

Describe the result you need. AI will set up the tool and ask for any missing details.

Configure with AI

Enter to submit · Shift + Enter for a new line

Sent to AI. Leave out passwords and private customer data.

Your details

Paper
Tax
Content

Order Printer Liquid template

invoice.liquid
{%- comment -%}
  Invoice {{ order.name }} — Liquid template for Shopify's Order Printer app.
  Paste this into Order Printer > your template > Edit code, or create a new template with it.
{%- endcomment -%}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Invoice {{ order.name }}</title>
<style>
  * { box-sizing: border-box; }
  body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif; color: #111; margin: 0; padding: 32px; font-size: 13px; line-height: 1.5; background: #fff; }
  .doc { max-width: 760px; margin: 0 auto; }
  .row { display: flex; justify-content: space-between; gap: 24px; }
  .head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 28px; gap: 16px; }
  h1 { font-size: 22px; margin: 0 0 4px; letter-spacing: -0.02em; }
  h2 { font-size: 12px; text-transform: uppercase; letter-spacing: 0.06em; color: #666; margin: 24px 0 8px; }
  table { width: 100%; border-collapse: collapse; margin-top: 8px; }
  th, td { text-align: left; padding: 8px 10px; border-bottom: 1px solid #e3e3e3; font-size: 12.5px; }
  th { text-transform: uppercase; font-size: 10.5px; letter-spacing: 0.05em; color: #666; border-bottom: 2px solid #111; }
  td.num, th.num { text-align: right; }
  .totals { margin-top: 12px; width: 260px; margin-left: auto; }
  .totals div { display: flex; justify-content: space-between; padding: 4px 0; }
  .totals .grand { font-weight: 700; border-top: 2px solid #111; margin-top: 4px; padding-top: 8px; font-size: 15px; }
  .muted { color: #666; }
  .box { border: 1px solid #ddd; border-radius: 8px; padding: 12px 14px; }
  .scan { text-align: center; }
  @media print { body { padding: 0; } @page { size: auto; margin: 12mm; } }
@media print { @page { size: A4; margin: 14mm; } }</style>
</head>
<body>
<div class="doc">
<div class="head">
  <div>
    <h1>Invoice</h1>
    <p class="muted">{{ order.name }} · {{ order.created_at | date: "%B %d, %Y" }}</p>
  </div>
  <div class="box" style="text-align:right">
    <p><strong>{{ shop.name }}</strong></p>
    {%- if shop.email %}<p class="muted">{{ shop.email }}</p>{% endif -%}
  </div>
</div>
<div class="row">
  <div>
    <h2>Bill to</h2>
    <p><strong>{{ billing_address.name }}</strong></p>
    <p class="muted">
      {{ billing_address.address1 }}{% if billing_address.address2 != blank %}<br>{{ billing_address.address2 }}{% endif %}<br>
      {{ billing_address.city }}, {{ billing_address.province_code }} {{ billing_address.zip }}<br>
      {{ billing_address.country }}
    </p>
  </div>
  <div style="text-align:right">
    <h2>Payment</h2>
    <p>Status: {{ order.financial_status | capitalize }}</p>
    <p>Email: {{ order.email }}</p>
  </div>
</div>
<table>
  <thead>
    <tr>
      <th>SKU</th>
      <th>Item</th>
      <th class="num">Qty</th>
      <th class="num">Unit price</th>
      <th class="num">Amount</th>
    </tr>
  </thead>
  <tbody>
    {%- for line in line_items -%}
    <tr>
      <td>{{ line.sku }}</td>
      <td>{{ line.title }}{% if line.variant_title != blank and line.variant_title != "Default Title" %} ({{ line.variant_title }}){% endif %}</td>
      <td class="num">{{ line.quantity }}</td>
      <td class="num">{{ line.price | money }}</td>
      <td class="num">{{ line.line_price | money }}</td>
    </tr>
    {%- endfor -%}
  </tbody>
</table>
{%- if discounts.size > 0 %}
<h2>Discounts</h2>
{%- for discount in discounts %}
<p class="muted">{{ discount.code }}: -{{ discount.amount | money }}</p>
{%- endfor %}
{%- endif %}
<div class="totals">
  <div><span>Subtotal</span><span>{{ subtotal_price | money }}</span></div>
  <div><span>Shipping</span><span>{{ shipping_price | money }}</span></div>
  {%- for tax_line in tax_lines %}
  <div><span>{{ tax_line.title }} ({{ tax_line.rate | times: 100 }}%)</span><span>{{ tax_line.price | money }}</span></div>
  {%- endfor %}
  <div class="grand"><span>Total</span><span>{{ total_price | money }}</span></div>
</div>
<p class="muted" style="margin-top:24px">Thank you for your order. Questions? Contact {{ shop.email }}.</p>
</div>
</body>
</html>

This Liquid uses the objects Shopify's free Order Printer app provides (order, line_items, shop, billing_address, shipping_address, discounts, tax_lines). Order Printer no longer shows up as a new install on the Shopify App Store; stores that already have it keep it and can edit its templates. If you don't have it, use the built-in Orders > Export/Print bulk action for a plain version, or a paid app (Order Printer Templates, Order Printer Pro) if you want this Liquid customized visually without code.

{{ tax_line.rate }} is a decimal (0.23 for 23%), which is why the template multiplies it by 100. If your store doesn't collect tax, the totals block still renders correctly at $0.00.

Live preview

What's in the template

Billing address, line items, discounts, and a totals block built from Order Printer's Liquid objects (subtotal_price, shipping_price, tax_lines, total_price). Turn on a full tax breakdown to list each tax_line by name and rate (useful for VAT/GST, where the rate has to show on the invoice), or keep a single tax line for simpler US sales tax setups.

tax_line.rate is a decimal (0.23 for 23%), so the template multiplies it by 100 to display it as a percentage.

Where this fits

Same as the packing slip template: this Liquid is written for Shopify's Order Printer app, which no longer shows up as a new install on the App Store. Existing installs can still use and edit it. Add your VAT/GST number in the generator so it prints on every invoice.

Questions people ask

Is this a legal tax invoice in my country?

It includes the fields most VAT/GST invoices require (seller details, tax number, tax rate and amount, totals), but invoice requirements vary by country. Check your local rules before relying on it for compliance.

Can I show multiple tax rates on one invoice?

Yes, turn on the tax breakdown option, which loops through every tax_line on the order rather than showing one combined total.

Does it handle discounts?

Yes, it lists each discount code and amount from the order's discounts before the totals block.

What if my store doesn't collect tax?

The totals block still renders correctly, showing $0.00 tax.

Want this builtinto your store?

I'm Emmanuel, a Shopify and WooCommerce developer. If this tool pointed at something you'd rather have fixed for you (a faster store, cleaner product data, a migration, a custom feature), send me a note.

Emmanuel Asika

Emmanuel Asika

Shopify & WooCommerce developer, Dublin

I build and fix online stores: new builds, migrations, speed, SEO and the custom bits apps can't do.

hello@emmanuelasika.com