Generating receipts at checkout without slowing the checkout

The receipt PDF should never sit between the customer and the order confirmation. A pattern: confirm first, render asynchronously, attach when ready.

Updated 31 August 2026

The worst place to render a PDF is inside the request that completes a purchase. A slow render, a busy renderer, a font server hiccup — and the customer sees a spinner after entering their card.

The pattern

1. Payment succeeds → order saved → confirmation page shown. No PDF yet. 2. Queue a render job with the order id and a webhook URL. 3. Webhook arrives → attach the receipt to the order → send the email with the link.

The customer gets the confirmation in under a second and the receipt email a few seconds later. Nobody notices the gap; everybody notices a spinner.

Idempotency

Payment providers retry webhooks. Key the render job on the order id and check before enqueueing, or you will send three receipts.

Storage

A signed, expiring link in the email is safer than an attachment: the file can be regenerated, the link can be revoked, and the email stays small. Seven days is enough for most customers; keep the ability to regenerate on request.

With PDFGeny

POST /api/v1/jobs
{"template":"receipt","data":{…},"filename":"receipt-1042.pdf","webhook_url":"https://shop.example/hooks/pdf"}

The webhook carries `document_url`; store it on the order and email it.

Try it: convert HTML to PDF in the browser, or get a free API key — 50 documents a month.

More guides

Writing HTML templates for PDF: a style guide (Jinja, Django, Handlebars)

Templates that render well as PDFs follow a few rules: fixed page geometry, no external state, defensive filters, print CSS. Examples in Jinja and Django syntax.

Issuing 5,000 course certificates in one afternoon

A spreadsheet of names, one landscape template, batch requests of 100, and signed links per student. The full workflow including naming, verification codes and delivery.

URL-to-PDF and SSRF: how a PDF renderer becomes an attack surface

A renderer that fetches URLs can be pointed at your internal network. The attacks, the defences, and what to demand from a PDF API vendor.

Why the PDF from headless Chromium differs from Print to PDF in the browser

Same engine, different output: viewport, print media, backgrounds, default margins, headless font rendering. A list of the differences and the option that fixes each.