Use Case
Invoice PDFs at scale
Generate invoice PDFs from billing webhooks (Stripe, Paddle, Chargebee, Lemon Squeezy, your own) at edge-runtime cost economics. Fill an invoice template with per-customer data, store + email the PDF in under a second, no headless Chrome or long-running backend.
Who this fits
- SaaS billing flows. Subscription invoices on payment-succeeded webhooks. Tax-compliant PDF on every charge.
- E-commerce platforms. Order receipts and tax invoices from order-completed webhooks. Multi-currency, multi-region.
- Freelance and consulting. Per-project invoices from time-tracking or project-management tools.
- Marketplaces. Per-transaction invoices for buyer + seller halves with different layouts.
The pattern, end-to-end
The canonical shape is a webhook handler that fills an invoice template and stores the result. From the billing-system event to a customer-readable PDF link is typically under 300ms end-to-end:
- Billing system → your webhook handler (Stripe
payment_intent.succeeded, Paddletransaction.completed, etc.). Verify the signature. - Handler → object storage: fetch the invoice template PDF (~10-30ms).
- Handler → PDFops:
POST /api/fill-formwith the template + the billing-event data as field values (~100-200ms including network). - Handler → object storage: stash the filled PDF for later access (~30-50ms).
- Handler → email service: fire-and-forget transactional email with a presigned download URL.
- Handler → billing system:
200 OK.
Full walkthrough with code: Generating invoice PDFs from Stripe webhooks on Cloudflare Workers — ~50 lines of TypeScript, complete with template fetch, fill-form call, R2 stash, and email trigger.
Try it
Grab the sample invoice-template.pdf (it has customer_name + total AcroForm fields ready to fill), then:
curl -X POST https://pdfops.dev/api/fill-form \
-F "pdf=@invoice-template.pdf" \
-F 'fields={"customer_name":"Acme Co","total":"$1,250.00"}' \
-o filled-invoice.pdf
For your real templates, name your AcroForm fields customer_name, amount, currency, invoice_id, date, due_date, line_item_1_desc, line_item_1_amount, etc. — short predictable names that survive your template editor's annual quirks. Full reference at the fill-form docs.
Variations
- Subscription invoices. Same template, same shape. The webhook fires once per period (monthly, annually) on renewal.
- One-off invoices. Fires on a manual-charge event or a recurring-charge-failed retry. Template can be the same or a "past-due" variant.
- Refund credits. Use a separate credit-memo template; fill it from a
charge.refundedevent. Same primitives. - Multi-currency. Template-per-currency in object storage, branch in the handler. PDF-LIB handles right-to-left scripts and non-Latin fonts if you embed the right font in the template.
- Multi-jurisdiction tax compliance. Per-region template (e.g. EU VAT, US sales tax, Indian GST). The handler picks the right template based on customer.address.country.
- Batch invoices (monthly statements). See monthly PDF bundles on a Cloudflare Cron Trigger — pairs
/api/fill-form+/api/mergefor per-customer statement compilations.
FAQ
Why generate invoice PDFs at all?
Three reasons most billing systems still emit them: compliance (many jurisdictions require an immutable document for tax or audit), email (PDF-attached invoices have higher open rates and survive recipient inbox archival), and accounting integration (bookkeeping tools ingest PDF invoices for expense matching).
Where does the template come from?
Author once in Acrobat, Mac Preview, LibreOffice Draw, or pdftk. Store it in your repo or object storage. Most billing systems have 1-3 template variants; they all fit in a few hundred KB.
How do I handle variable-count line items?
Either fixed-line-count templates with up to N rows (leave empty blank — works for most SaaS where line counts are predictable per tier), or build a per-invoice template at request time (more work but supports arbitrary counts). Start with (1).
What's the cost math at 10k invoices/month?
DocRaptor / PDFShift / PDFMonkey: $50-$2,000/mo. Headless Chrome on Lambda: ~$10-$30/mo of compute plus ops cost. PDFops post-beta: priced at roughly 10× cheaper per document than incumbents, with no subscription floor. Compare in detail on /vs/docraptor, /vs/pdfshift, /vs/pdfmonkey.
Where do I store the generated PDFs?
PDFops returns the bytes; your code decides. Common patterns: Vercel Blob, Cloudflare R2, S3 with presigned URLs, or an authed route on your own domain. Pair with a retention policy for long-term archive.
Get higher-tier access
The anonymous tier (100/IP/month) is fine for evaluation. For production volume, join the waitlist — keys with 1,000-10,000/month quotas are coming, free during beta, with locked-in pricing post-beta. The form's message field is where you tell me about your specific volume and migration timeline.
← PDFops home · Docs · Blog