Transform your billing workflow with a language-agnostic API that generates professional invoice PDFs from your existing payment and customer data, regardless of your backend technology stack.
When you're building applications that handle payments, subscriptions, or any form of billing, invoice generation becomes an inevitable requirement. Your customers expect professional invoices for their records, your accounting team needs standardized documents for bookkeeping, and regulatory compliance often mandates proper invoice formatting and numbering.
The traditional approach forces you to choose between building a custom PDF generation system from scratch or integrating heavy document libraries into your codebase. Custom solutions require deep knowledge of PDF formatting, font handling, and layout engines. Library-based approaches tie you to specific programming languages and create maintenance overhead when document requirements change. Both paths divert development time from your core business logic into document formatting concerns.
This challenge becomes particularly acute when you consider that invoice formatting is rarely a one-time decision. Business requirements evolve, branding guidelines change, and different customer segments may require different invoice styles. What starts as a simple PDF generation task becomes an ongoing maintenance burden that touches multiple parts of your application.
Instead of embedding invoice generation logic directly in your application, you extract your billing data into a standardized JSON format and send it to a specialized API along with a Liquid template that defines your invoice layout. This approach separates your payment processing logic from your document presentation logic, allowing each to evolve independently.
The beauty of this architecture lies in its simplicity. Your backend continues to handle payments, track customer data, and manage billing cycles exactly as it does today. When an invoice needs to be generated, you make a single API call with your data and receive back a professional PDF that matches your brand guidelines and formatting requirements.
# Your backend sends structured billing data to the invoice API
curl --request POST \
--url https://dash.liquidtemplater.com/items/template_request \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'content-type: application/json' \
--data '{
"data": {
"invoice": {
"number": "INV-2025-1247",
"issue_date": "2025-06-21",
"due_date": "2025-07-21",
"company": {
"name": "Your Company LLC",
"address": "456 Business District",
"city": "San Francisco",
"state": "CA",
"zip": "94105",
"tax_id": "12-3456789"
},
"customer": {
"name": "Acme Corporation",
"email": "billing@acme.com",
"address": "789 Client Street",
"city": "New York",
"state": "NY",
"zip": "10001"
},
"line_items": [
{
"description": "Monthly SaaS Subscription - Pro Plan",
"quantity": 1,
"unit_price": 299.00,
"total": 299.00
},
{
"description": "Additional User Licenses (5 users)",
"quantity": 5,
"unit_price": 25.00,
"total": 125.00
}
],
"subtotal": 424.00,
"tax_rate": 8.25,
"tax_amount": 34.98,
"total": 458.98
}
},
"template": "<!-- Your branded invoice template -->",
"type": "pdf"
}'
This request structure maps directly to the data you already maintain in your billing system. Customer information comes from your user database, line items reflect your pricing structure, and totals represent calculations your backend already performs. The API handles the complex work of PDF generation, font rendering, and cross-platform compatibility while you focus on accuracy and business logic.
Liquid templating provides the ideal balance between design flexibility and maintainability for invoice generation. Unlike hardcoded PDF libraries that require developer intervention for every visual change, Liquid templates can be modified by non-technical team members while maintaining the data binding logic that ensures accuracy.
Understanding how to structure your invoice template helps you create documents that look professional while remaining easy to maintain. The template below demonstrates the key sections that most invoices require, along with the data binding patterns that connect your backend data to the final document.
<!-- Invoice Header Section -->
<div class="invoice-header">
<div class="company-info">
<h1>{{ invoice.company.name }}</h1>
<p>{{ invoice.company.address }}</p>
<p>{{ invoice.company.city }}, {{ invoice.company.state }} {{ invoice.company.zip }}</p>
<p>Tax ID: {{ invoice.company.tax_id }}</p>
</div>
<div class="invoice-details">
<h2>Invoice #{{ invoice.number }}</h2>
<p>Issue Date: {{ invoice.issue_date | date: "%B %d, %Y" }}</p>
<p>Due Date: {{ invoice.due_date | date: "%B %d, %Y" }}</p>
</div>
</div>
<!-- Customer Information Section -->
<div class="bill-to-section">
<h3>Bill To:</h3>
<p><strong>{{ invoice.customer.name }}</strong></p>
<p>{{ invoice.customer.address }}</p>
<p>{{ invoice.customer.city }}, {{ invoice.customer.state }} {{ invoice.customer.zip }}</p>
<p>{{ invoice.customer.email }}</p>
</div>
<!-- Line Items Table -->
<table class="invoice-items">
<thead>
<tr>
<th>Description</th>
<th>Quantity</th>
<th>Unit Price</th>
<th>Total</th>
</tr>
</thead>
<tbody>
{% for item in invoice.line_items %}
<tr>
<td>{{ item.description }}</td>
<td>{{ item.quantity }}</td>
<td>${{ item.unit_price | number_format: 2 }}</td>
<td>${{ item.total | number_format: 2 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- Totals Section -->
<div class="invoice-totals">
<div class="totals-row">
<span>Subtotal:</span>
<span>${{ invoice.subtotal | number_format: 2 }}</span>
</div>
{% if invoice.tax_rate > 0 %}
<div class="totals-row">
<span>Tax ({{ invoice.tax_rate }}%):</span>
<span>${{ invoice.tax_amount | number_format: 2 }}</span>
</div>
{% endif %}
<div class="totals-row total-row">
<span><strong>Total:</strong></span>
<span><strong>${{ invoice.total | number_format: 2 }}</strong></span>
</div>
</div>
<!-- Payment Terms and Notes -->
<div class="invoice-footer">
<p><strong>Payment Terms:</strong> Net 30 days</p>
<p>Thank you for your business!</p>
</div>
This template structure demonstrates several important concepts that make invoice generation both flexible and maintainable. The data binding uses dot notation to access nested objects, which maps naturally to how most backends structure customer and billing data. The conditional logic around tax display shows how templates can adapt to different billing scenarios without requiring separate template files. The number formatting filters ensure that currency values display consistently regardless of how your backend stores decimal precision.
The API-driven approach means that invoice generation works identically whether your backend is built with Node.js, Python, Ruby, Go, PHP, or any other technology. The integration pattern remains consistent because it relies on standard HTTP requests and JSON data exchange rather than language-specific libraries or dependencies.
Here's how the integration typically works within a backend payment processing workflow. When a payment is completed or a billing cycle triggers invoice creation, your existing code extracts the relevant data and formats it according to the API specification.
// Example backend integration in Node.js/Express
// This same pattern works in any language that can make HTTP requests
const generateInvoice = async (paymentId) => {
// Step 1: Gather invoice data from your existing database queries
// This is the same data you already track for payments and customers
const payment = await db.payments.findById(paymentId, {
include: ['customer', 'line_items']
});
// Step 2: Format the data according to your invoice template requirements
// Notice how this maps directly to your existing data structure
const invoiceData = {
invoice: {
number: generateInvoiceNumber(payment.id), // Your existing numbering logic
issue_date: new Date().toISOString().split('T')[0],
due_date: calculateDueDate(payment.terms), // Your payment terms logic
company: getCompanyInfo(), // Your company details
customer: {
name: payment.customer.company_name,
email: payment.customer.billing_email,
address: payment.customer.billing_address,
city: payment.customer.billing_city,
state: payment.customer.billing_state,
zip: payment.customer.billing_zip
},
line_items: payment.line_items.map(item => ({
description: item.product_name,
quantity: item.quantity,
unit_price: item.unit_price,
total: item.quantity * item.unit_price
})),
subtotal: payment.subtotal,
tax_rate: payment.tax_rate,
tax_amount: payment.tax_amount,
total: payment.total
}
};
// Step 3: Submit to invoice generation API
// The template can be stored in your database, config files, or version control
const response = await fetch('https://dash.liquidtemplater.com/items/template_request', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.INVOICE_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
data: invoiceData,
template: await loadInvoiceTemplate(), // Your template loading logic
type: 'pdf'
})
});
const { data } = await response.json();
// Step 4: Store the generation request ID for tracking
// This allows you to poll for completion and manage the async workflow
await db.invoices.create({
payment_id: paymentId,
invoice_number: invoiceData.invoice.number,
generation_request_id: data.id,
status: 'generating',
created_at: new Date()
});
return data.id; // Return the request ID for polling
};
// Step 5: Poll for completion (PDFs typically take 10 seconds)
// This can run as a background job or webhook handler
const checkInvoiceGeneration = async (requestId) => {
const response = await fetch(`https://dash.liquidtemplater.com/items/template_request/${requestId}`, {
headers: {
'Authorization': `Bearer ${process.env.INVOICE_API_KEY}`
}
});
const status = await response.json();
if (status.data.fullfilled_on && status.data.result) {
// Invoice PDF is ready for download
const downloadUrl = `https://dash.liquidtemplater.com/assets/${status.data.result}?download=true`;
// Update your database to reflect completion
await db.invoices.update(
{ generation_request_id: requestId },
{
status: 'completed',
pdf_asset_id: status.data.result,
download_url: downloadUrl,
completed_at: status.data.fullfilled_on
}
);
// Optionally notify customer that invoice is ready
await sendInvoiceNotification(downloadUrl);
return downloadUrl;
}
return null; // Still processing
};
This integration pattern demonstrates how invoice generation becomes a natural extension of your existing payment processing workflow. The data transformation step maps your current database schema to the invoice template requirements, but it doesn't require changes to your core business logic or database structure. The asynchronous polling mechanism fits well with background job systems that most payment processing applications already use for tasks like sending confirmation emails or updating analytics.
Understanding specific use cases helps clarify how invoice automation fits into different business models and technical architectures. These scenarios represent common patterns that demonstrate the flexibility of API-driven invoice generation while highlighting the business value of automated document creation.
Subscription Business Automation: For SaaS applications or subscription services, invoice generation typically occurs on billing cycle boundaries. Your existing subscription management logic determines when to charge customers, what amounts to bill, and which services to include. Invoice automation extends this workflow by automatically generating professional invoices that match each customer's billing data, subscription tier, and usage patterns. The same system that calculates recurring charges can trigger invoice creation without additional complexity.
E-commerce Order Processing: Online stores need to convert completed orders into invoices for customer records and accounting purposes. Your existing order fulfillment system already tracks product details, shipping information, customer data, and payment processing. Invoice generation becomes an additional step in the order completion workflow, producing professional invoices that customers can use for expense reporting or business accounting. The template system allows different invoice styles for different customer types, such as retail customers versus wholesale accounts.
Professional Services Billing: Consulting firms, agencies, and freelancers often need to convert time tracking data and project milestones into client invoices. Your existing project management system captures billable hours, expense tracking, and client information. Invoice automation transforms this operational data into client-ready documents without manual formatting or calculation errors. The template flexibility supports different billing structures, whether you charge hourly rates, fixed project fees, or retainer arrangements.
Marketplace Transaction Processing: Multi-vendor platforms need to generate invoices for transactions between buyers and sellers while handling commission structures and fee calculations. Your marketplace backend already manages vendor relationships, transaction tracking, and financial settlements. Invoice automation can generate separate invoices for buyers (showing their purchases) and sellers (showing their earnings after commissions), using the same transaction data with different template presentations.
Real-world invoicing often involves requirements beyond basic line item billing. Understanding how to handle these complexities within the template and API structure helps you build systems that scale with business needs rather than requiring constant customization.
Multi-Currency Support: For businesses that operate internationally, invoices need to display appropriate currency symbols, formatting conventions, and exchange rate information. Your backend maintains currency data as part of payment processing, and Liquid templates can format these values according to regional conventions. The template system supports conditional logic that adapts presentation based on customer location or preferred currency.
Tax Calculation Complexity: Different jurisdictions require different tax display formats, multiple tax types, or specific compliance information. Your existing tax calculation logic determines the correct amounts and rates, while the template system handles the presentation requirements. Templates can conditionally display tax breakdowns, compliance numbers, or regulatory text based on customer location and business rules.
Volume Discounts and Promotional Pricing: Many businesses offer tiered pricing, bulk discounts, or promotional rates that need clear explanation on invoices. Your pricing engine calculates the final amounts and discount applications, while invoice templates can display the discount logic in customer-friendly formats. This separation allows your business rules to evolve without requiring changes to document formatting code.
Custom Fields and Branding: Different customer segments may require different invoice formats, additional data fields, or customized branding. The template system supports conditional sections and variable content that adapts based on customer attributes stored in your backend. You can maintain multiple template variations or use conditional logic within a single template to handle these requirements.
Beginning your invoice automation implementation requires understanding how your current billing workflow maps to the API integration pattern. The most effective approach starts with identifying where in your existing payment processing flow invoice generation should occur, then determining what data transformations are needed to convert your database records into the template format.
The API documentation provides comprehensive details about request formatting, authentication requirements, and response handling that help you plan the technical integration. For template development and testing, the interactive demo allows you to experiment with invoice layouts using sample data that mirrors typical billing scenarios.
Understanding the template syntax helps you create invoice templates that handle the conditional logic, formatting requirements, and data binding patterns that professional invoices require. The template system provides filters for currency formatting, date display, and mathematical calculations that eliminate common invoice formatting challenges.
Invoice generation involves sensitive business and customer information that requires appropriate security measures and compliance considerations. The API processes invoice data transiently during document generation, with completed PDFs stored temporarily for seven days in GDPR-compliant infrastructure hosted in Germany.
This approach provides the security and compliance benefits of professional data handling without requiring long-term storage infrastructure on your end. Your sensitive customer and billing data remains in your control while leveraging professional document generation capabilities. For businesses handling regulated financial data or international customer information, this European hosting and minimal retention policy provides necessary data protection without sacrificing invoice automation functionality.
The temporary storage period gives your application sufficient time to download and archive invoices according to your own data retention policies while ensuring that the document generation service doesn't become a long-term repository for sensitive business information.