Pay-per-use · No subscriptions

Generate payment and order receipts from HTML — in any size

A4, Letter, or thermal 80mm. One API call after every transaction.

Render branded payment receipts, order confirmations, and POS slips as PDFs from simple HTML templates. Supports standard paper sizes and thermal widths (80mm / 58mm). Plugs into any checkout flow — Razorpay, Stripe, PayPal, Shopify, or your custom stack. Pay only when a receipt is generated.

Why developers choose HTML2DocHub

Any paper size: A4, Letter, or thermal 80mm / 58mm receipt widths
Template once in HTML + CSS, swap variables per transaction
Works after every payment — Razorpay, Stripe, PayPal, UPI, cash register
Signed download URL — email it, store it, or attach to the confirmation page
Async mode for high-volume checkouts so you don't block the response
Idempotency keys so a payment retry never generates a duplicate receipt
GST / VAT line items render correctly with flexbox and grid CSS
Per-receipt charge visible in your dashboard — no monthly subscription

Code Examples

Template — A4 receipt with Tailwind-style CSShtml
<!DOCTYPE html>
<html>
<head><style>
  @page { size: A4; margin: 15mm; }
  body { font-family: system-ui, sans-serif; color: #111; }
  .header { display: flex; justify-content: space-between; border-bottom: 2px solid #111; padding-bottom: 8px; }
  .brand { font-size: 20px; font-weight: 700; }
  .meta  { color: #666; font-size: 12px; text-align: right; }
  table  { width: 100%; border-collapse: collapse; margin-top: 24px; }
  th, td { padding: 8px 0; border-bottom: 1px solid #eee; text-align: left; font-size: 13px; }
  .total { font-weight: 700; border-bottom: none; padding-top: 12px; }
</style></head>
<body>
  <div class="header">
    <div class="brand">ACME STORE</div>
    <div class="meta">Receipt #R-{{orderId}}<br/>{{orderDate}}</div>
  </div>
  <table>
    <thead><tr><th>Item</th><th style="text-align:right">Qty</th><th style="text-align:right">Amount</th></tr></thead>
    <tbody>
      {{#items}}
        <tr><td>{{name}}</td><td style="text-align:right">{{qty}}</td><td style="text-align:right">₹{{amount}}</td></tr>
      {{/items}}
      <tr class="total"><td colspan="2">Total</td><td style="text-align:right">₹{{total}}</td></tr>
    </tbody>
  </table>
</body>
</html>
Python — render after Razorpay payment capturepython
import requests
from jinja2 import Template

def generate_receipt(order):
    html = Template(open("templates/receipt.html").read()).render(
        orderId=order.id,
        orderDate=order.created_at.strftime("%d %b %Y %I:%M %p"),
        items=order.items,
        total=order.total,
    )

    resp = requests.post(
        "https://api.html2dochub.com/v1/render",
        headers={"X-API-Key": HTML2DOCHUB_KEY},
        json={
            "type": "pdf",
            "html": html,
            "options": {"format": "A4"},
            "tag": f"receipt:{order.id}",
            "idempotency_key": f"receipt-{order.id}",
        },
        timeout=30,
    )
    resp.raise_for_status()
    return resp.json()["download_url"]
Node — thermal 80mm POS receipttypescript
// 80mm thermal receipt — width tuned for POS printers
export async function renderThermalReceipt(order: Order): Promise<Buffer> {
  const html = renderTemplate("receipt-80mm", order);

  const res = await fetch("https://api.html2dochub.com/v1/render", {
    method: "POST",
    headers: {
      "X-API-Key": process.env.HTML2DOCHUB_API_KEY!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      type: "pdf",
      html,
      options: {
        // 80mm width, height scales to content
        width:  "80mm",
        height: "297mm",
        margin: { top: "2mm", bottom: "2mm", left: "2mm", right: "2mm" },
        print_background: true,
      },
      tag: `pos-receipt:${order.id}`,
      idempotency_key: `pos-receipt-${order.id}`,
    }),
  });
  const job = await res.json();
  const pdfRes = await fetch(job.download_url);
  return Buffer.from(await pdfRes.arrayBuffer());
}

Simple, transparent pricing

Pay only for pages rendered. No subscriptions. No minimum monthly fee.

1 page PDF:~₹0.10
10 page PDF:~₹0.80
100 pages/day:~₹8/day
See full pricing details

Frequently Asked Questions

Can I generate thermal receipts for POS printers?+
Yes. Set width to 80mm (or 58mm) with a tall height (297mm works for most receipts). The printer driver crops to the actual content length. Use small font sizes (10–11pt) and tight margins (2–3mm) for best fit.
How do I make sure each payment generates exactly one receipt?+
Pass an idempotency_key equal to your order ID. If a retry or webhook replay triggers a second render for the same key, we return the original receipt instead of generating a new one — and you're only billed once.
Will GST / VAT / tax line items render correctly?+
Yes. Use regular HTML tables or CSS grid. Chromium handles flexbox gaps and grid layouts exactly as they render in the browser, so aligned currency columns look correct in the PDF.
Can I email the receipt automatically after payment?+
The API returns a signed download_url pointing to the PDF on our storage. Fetch the bytes, attach to your transactional email (Resend, Postmark, SendGrid), and send. Typical flow: payment webhook → render receipt → email receipt → 2 seconds total.
What about Razorpay + HTML2DocHub specifically?+
That's exactly the stack this platform is built on. Subscribe to Razorpay's payment.captured webhook, render the receipt in the handler, email it. The whole flow is usually under 50 lines of code.

Start rendering PDFs today

Free account. No credit card required. API ready in minutes.

Get your free API key