Selling and buying / A4
Order confirmation HTML template
Sent to the buyer after an order is placed: what was ordered, what it cost, and above all when it will arrive.
When this document is the right one
An order is accepted and payment has cleared. It is not an invoice and not a receipt: it is an acknowledgement that closes the loop, and its job is to stop the customer emailing to ask whether the order went through.
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.
- The expected delivery window, above everything else including the total. That is the only question the reader has.
- A statement that nothing further is needed from them, because the second most common reason for a follow-up email is uncertainty about whether an action is outstanding.
- Back-ordered lines flagged with what happens to them, rather than left to be discovered when a short parcel arrives.
- Both addresses, because a delivery address typed into a form at eleven at night is the field most worth checking while it can still be changed.
- A numbered list of what happens next, with a deadline for any choice the customer can still make.
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>Order confirmation ORD-99031</title>
<style>
@page { size: A4; margin: 18mm 16mm; }
* { box-sizing: border-box; }
body { margin: 0; font: 10pt/1.5 "Helvetica Neue", Arial, sans-serif; color: #111; }
header { display: flex; justify-content: space-between; align-items: flex-start;
border-bottom: 2px solid #111; padding-bottom: 6mm; }
h1 { margin: 0; font-size: 19pt; }
.thanks { color: #555; margin-top: 1.5mm; }
.ref { text-align: right; font-size: 9pt; }
.ref .no { font-size: 13pt; font-weight: 700; }
/* An order confirmation is read for one thing: when it arrives. That answer
goes above everything else, including the price. */
.eta { margin: 7mm 0; border: 1.5px solid #111; padding: 4mm 5mm;
display: flex; justify-content: space-between; align-items: center; }
.eta .k { font-size: 8pt; text-transform: uppercase; letter-spacing: 0.08em; color: #666; }
.eta .v { font-size: 15pt; font-weight: 700; }
.addresses { display: grid; grid-template-columns: 1fr 1fr; gap: 10mm; margin-bottom: 7mm; }
.addresses h2 { margin: 0 0 2mm; font-size: 8pt; text-transform: uppercase;
letter-spacing: 0.08em; color: #666; }
address { font-style: normal; }
table { width: 100%; border-collapse: collapse; }
thead { display: table-header-group; }
th { text-align: left; font-size: 8pt; text-transform: uppercase; letter-spacing: 0.06em;
color: #666; border-bottom: 1.5px solid #111; padding-bottom: 2mm; }
td { padding: 2.5mm 0; border-bottom: 1px solid #eee; vertical-align: top; }
tr { break-inside: avoid; }
.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.backorder { color: #8a5300; font-size: 8.5pt; display: block; margin-top: 0.8mm; }
.totals { width: 78mm; margin: 5mm 0 0 auto; break-inside: avoid; }
.totals div { display: flex; justify-content: space-between; padding: 1.4mm 0; }
.totals .grand { border-top: 1.5px solid #111; margin-top: 2mm; padding-top: 2.5mm;
font-size: 12pt; font-weight: 700; }
.next { margin-top: 10mm; border-top: 1px solid #eee; padding-top: 5mm;
font-size: 9pt; break-inside: avoid; }
.next h2 { margin: 0 0 2mm; font-size: 9pt; }
.next ol { margin: 0; padding-left: 5mm; }
</style>
</head>
<body>
<header>
<div>
<h1>Order confirmed</h1>
<div class="thanks">Thank you. Nothing further is needed from you.</div>
</div>
<div class="ref">
<div class="no">ORD-99031</div>
Placed 12 May 2026, 09:41<br>
Payment received in full
</div>
</header>
<div class="eta">
<div>
<div class="k">Expected delivery</div>
<div class="v">Thursday 21 to Friday 22 May</div>
</div>
<div style="text-align:right">
<div class="k">Shipping</div>
<div>Standard, tracked</div>
</div>
</div>
<section class="addresses">
<div>
<h2>Delivery address</h2>
<address><strong>H. Ashworth</strong><br>41 Sylvan Road<br>Exeter EX4 6EW</address>
</div>
<div>
<h2>Billing address</h2>
<address><strong>H. Ashworth</strong><br>41 Sylvan Road<br>Exeter EX4 6EW<br>
Paid by Visa ending 4021</address>
</div>
</section>
<table>
<thead>
<tr><th>Item</th><th class="num">Qty</th><th class="num">Unit</th><th class="num">Total</th></tr>
</thead>
<tbody>
<tr><td>Cold brew concentrate, 1L</td><td class="num">2</td>
<td class="num">14.00</td><td class="num">28.00</td></tr>
<tr><td>House blend beans, 500g, whole</td><td class="num">3</td>
<td class="num">11.50</td><td class="num">34.50</td></tr>
<tr>
<td>Ceramic pour-over, matte white
<span class="backorder">1 in stock now, 1 expected 20 May. Both ship together
unless you ask us to split the order.</span></td>
<td class="num">2</td><td class="num">26.00</td><td class="num">52.00</td>
</tr>
</tbody>
</table>
<div class="totals">
<div><span>Subtotal</span><span>114.50</span></div>
<div><span>Shipping</span><span>4.95</span></div>
<div><span>VAT at 20%</span><span>23.89</span></div>
<div class="grand"><span>Paid</span><span>GBP 143.34</span></div>
</div>
<section class="next">
<h2>What happens next</h2>
<ol>
<li>We pack the order. You will get a tracking number by email when it leaves us.</li>
<li>The back-ordered item arrives with us on 20 May and ships with the rest.</li>
<li>If you would rather have the in-stock items now, reply to this order by 18 May and we will split the shipment at no extra cost.</li>
</ol>
</section>
</body>
</html>The layout decision worth understanding
The delivery window is set in a bordered block with the price nowhere near it. Every instinct in an ecommerce template is to lead with the total, and the total is the one number the customer has already agreed to. The date is the new information.
The mistake people make adapting it
Sending this instead of a receipt, or instead of an invoice. It is neither: it does not evidence a payment and it does not demand one. A business customer who needs a document for their records needs an invoice, and an order confirmation filed as one causes a problem months later.
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 sales-order.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 order confirmation 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.
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.
Purchase order HTML template
Issued by the buyer: an instruction to supply specific goods at specific prices, with separate delivery and invoicing addresses and the conditions of the order.
Trade price list PDF template
A dated catalogue of prices by item code, usually with a second column for volume, issued to trade accounts.
Product datasheet PDF template
A two-column technical specification sheet with a revision number, grouped tables, a dimensions figure and an ordering code.
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.
Payment receipt HTML template
Proof that a payment was made: the amount, the payment reference, the method, and what it was for.
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.