Billing and receivables / A4
Commercial invoice template for customs
The customs document that travels with an international shipment: what the goods are, what they are worth, where they were made, and under what terms they move.
When this document is the right one
Goods cross a border. Customs on the importing side uses this document to classify the goods, assess duty and decide whether the consignment moves or waits, so the audience is an official rather than an accounts department.
Why each part is there
The fields are visible in the markup. What is not visible is why they are present, which is the part that gets removed first when someone adapts a template for their own use.
- An HS code per line, because that is what duty is assessed on and a wrong code is the difference between zero and twelve per cent.
- Country of origin per line, which is where the goods were made rather than where they were shipped from.
- Incoterms, naming the rule and the year, because the term decides who pays freight and duty and where risk passes.
- Gross and net weight and the number of packages, which is what the carrier and the customs entry are reconciled against.
- The value broken into goods, freight and insurance, since some regimes assess on the goods value and some on the delivered value.
- A signed declaration that the particulars are true, which is what makes this a legal statement rather than a packing note.
The template
A complete file. Doctype, stylesheet, body: paste it into a renderer unchanged and it produces a finished A4 page. Replace the sample data and the styling holds.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Commercial invoice CI-2026-0071</title>
<style>
@page { size: A4; margin: 12mm; }
* { box-sizing: border-box; }
body { margin: 0; font: 8.5pt/1.35 Arial, sans-serif; color: #000; }
h1 { margin: 0 0 3mm; font-size: 13pt; text-align: center;
letter-spacing: 0.1em; text-transform: uppercase; }
.grid { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid #000; }
.cell { padding: 2.5mm 3mm; border-right: 1px solid #000; border-bottom: 1px solid #000; }
.cell:nth-child(even) { border-right: 0; }
.cell h2 { margin: 0 0 1mm; font-size: 7pt; text-transform: uppercase;
letter-spacing: 0.06em; color: #333; }
address { font-style: normal; }
table { width: 100%; border-collapse: collapse; margin-top: 4mm; }
thead { display: table-header-group; }
th, td { border: 1px solid #000; padding: 1.8mm; }
th { background: #eee; font-size: 7.5pt; text-align: left; }
tr { break-inside: avoid; }
.num { text-align: right; font-variant-numeric: tabular-nums; }
/* Customs reads the value, the origin and the tariff code. Everything else
on this document is context for those three fields. */
.customs-block { margin-top: 4mm; display: grid; grid-template-columns: 1fr 78mm;
gap: 5mm; break-inside: avoid; }
.totals div { display: flex; justify-content: space-between; padding: 1mm 0;
border-bottom: 1px solid #ddd; }
.totals .grand { border-bottom: 0; border-top: 2px solid #000; font-weight: 700;
font-size: 10.5pt; padding-top: 2mm; }
.declaration { margin-top: 6mm; border: 1px solid #000; padding: 3mm;
break-inside: avoid; }
.sign-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8mm; margin-top: 10mm; }
.sign-row div { border-top: 1px solid #000; padding-top: 1.5mm; font-size: 7.5pt; }
</style>
</head>
<body>
<h1>Commercial invoice</h1>
<div class="grid">
<div class="cell">
<h2>Exporter / shipper</h2>
<address><strong>Anantha Instruments Pvt Ltd</strong><br>
44/2 Hosur Road, Bengaluru 560068, India<br>
IEC 0788004411 · Tel +91 80 4112 8800</address>
</div>
<div class="cell">
<h2>Invoice details</h2>
Number: CI-2026-0071<br>Date: 14 May 2026<br>
Export reference: SB 4471129 / 12-05-2026
</div>
<div class="cell">
<h2>Consignee</h2>
<address><strong>Werkhaus Systeme GmbH</strong><br>
Lindenstrasse 44, 10969 Berlin, Germany<br>
EORI DE289410577</address>
</div>
<div class="cell">
<h2>Terms</h2>
Incoterms 2020: CIP Berlin<br>
Country of origin: India<br>
Country of final destination: Germany<br>
Payment: T/T 30 days from B/L date
</div>
<div class="cell">
<h2>Transport</h2>
Air waybill 098-44711223<br>
Port of loading: Bengaluru (BLR)<br>
Port of discharge: Berlin (BER)
</div>
<div class="cell">
<h2>Packages</h2>
3 cartons, marked WSG/BER/1-3<br>
Gross weight 61.4 kg · Net weight 54.0 kg<br>
Measurement 0.42 CBM
</div>
</div>
<table>
<thead>
<tr>
<th>Marks & numbers</th><th>Description of goods</th>
<th>HS code</th><th>Origin</th>
<th class="num">Qty</th><th class="num">Unit value</th><th class="num">Total value</th>
</tr>
</thead>
<tbody>
<tr>
<td>WSG/BER/1-2</td>
<td>Digital pressure transmitter, model DPT-200, 4-20mA output</td>
<td>9026.20</td><td>IN</td>
<td class="num">10 pcs</td><td class="num">88.00</td><td class="num">880.00</td>
</tr>
<tr>
<td>WSG/BER/3</td>
<td>Stainless steel mounting bracket, 316L</td>
<td>7326.90</td><td>IN</td>
<td class="num">10 pcs</td><td class="num">5.75</td><td class="num">57.50</td>
</tr>
</tbody>
</table>
<div class="customs-block">
<div>
<strong>Reason for export:</strong> sale<br>
<strong>Currency:</strong> EUR<br>
<strong>Dual use:</strong> not applicable, goods are not listed under
Annex I of Regulation (EU) 2021/821.
</div>
<div class="totals">
<div><span>Goods value (FOB)</span><span>937.50</span></div>
<div><span>Freight</span><span>210.00</span></div>
<div><span>Insurance</span><span>14.00</span></div>
<div class="grand"><span>CIP value</span><span>EUR 1,161.50</span></div>
</div>
</div>
<div class="declaration">
<strong>Declaration.</strong> I declare that the information given above is true and
complete, that the goods described are of Indian origin, and that the values stated
are the transaction values actually paid or payable.
<div class="sign-row">
<div>Name and position of signatory</div>
<div>Signature, place and date</div>
</div>
</div>
</body>
</html>The layout decision worth understanding
The header is a rigid two-column grid of bordered cells rather than a flowing layout. Customs brokers and freight systems scan these documents in a fixed reading order, and a design that moves the consignee block somewhere unexpected costs time at exactly the point where time is expensive.
The mistake people make adapting it
Copying the sales invoice value across without thought. A shipment sent free of charge, on consignment or as a sample still has a customs value, and declaring zero does not mean no duty, it means the entry is queried and the shipment stops.
Rendering it
The page box is declared in the template's own CSS as A4, so the size travels with the markup rather than living in the code that calls the renderer. A4 is also one of the six named formats the API accepts, so it can be passed in the request options instead if that suits your setup better.
curl -X POST https://api.pdfpipe.xyz/v1/pdf \
-H "Authorization: Bearer $PDFPIPE_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<!doctype html>...",
"options": { "format": "A4" }
}' \
--output commercial-invoice.pdfFrequently asked
Can I use this template commercially?
Yes. Copy it, change it, ship it. It is sample markup written to be taken, and the sample data in it is invented, so replace the names and the numbers before anyone sees it.
Why is the page size in the CSS rather than in the API call?
Because a commercial invoice is a A4 document, and that is a property of the document rather than of the code that renders it. Declaring it in the page box means the size cannot be lost between the template and the call, which is the usual way a document ends up on the wrong paper.
Will it look the same in every renderer?
The layout will, because it uses ordinary CSS. The page break behaviour will not: break-inside and break-after are implemented differently by browser engines and by dedicated print engines, and some of the paged media specification is not implemented in browser renders at all. That difference is documented per property in the paged CSS reference.
Other templates
Documents from the same part of a business, and one from each of the other groups.
HTML invoice template with CSS
The standard commercial invoice: a demand for payment with line items, a tax figure, and terms that say when the money is due.
EU VAT invoice HTML template
A cross-border invoice inside the EU, with both parties' VAT identification numbers, tax broken out per rate, and a reverse charge statement.
GST tax invoice HTML template for India
An Indian tax invoice with GSTIN for both parties, HSN codes per line, and tax split into CGST and SGST or charged as IGST depending on the place of supply.
Proforma invoice HTML template
A document shaped like an invoice that is deliberately not one: it commits nobody to pay and exists so the buyer can raise an order, open a credit, or clear an import.
Payment receipt HTML template
Proof that a payment was made: the amount, the payment reference, the method, and what it was for.
Quotation HTML template with CSS
A priced proposal with a validity date, a scope, optional items kept out of the headline total, and somewhere to sign.
Packing slip HTML template
The document that goes in the box: what was ordered, what was actually shipped, and no prices at all.
Every template
The full set, grouped by what part of a business produces the document.
A4 page size for PDF generation
A4 is the default page for business documents everywhere except North America, and the default this API uses when no format is given.
Paste the template into the playground and get the PDF back. No signup, no key.