
Invoice Generation Automation
- 72 installs
- 41 repo stars
- Updated March 13, 2026
- finsilabs/awesome-ecommerce-skills
Automatically generate branded PDF invoices with line items, tax breakdowns, and payment terms, integrated with accounting systems.
About
Turns completed orders into branded, legally-formatted PDF invoices via platform apps or plugins. A developer uses it for B2B invoicing, EU VAT-format compliance, or syncing invoices to QuickBooks/Xero.
- Per-platform invoice-tool selection guidance
- EU VAT requirements with sequential numbering and mandatory fields
Invoice Generation Automation by the numbers
- 72 all-time installs (skills.sh)
- Ranked #3,076 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
npx skills add https://github.com/finsilabs/awesome-ecommerce-skills --skill invoice-generation-automationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 72 |
|---|---|
| repo stars | ★ 41 |
| Last updated | March 13, 2026 |
| Repository | finsilabs/awesome-ecommerce-skills ↗ |
What it does
Automatically generate branded PDF invoices with line items, tax breakdowns, and payment terms, integrated with accounting systems.
Files
Invoice Generation Automation
Overview
Automated invoice generation turns every completed order into a professional, branded PDF invoice without manual effort. For B2B ecommerce, invoices are legal documents required for the customer's procurement and accounting workflows. In many countries — particularly within the EU — specific invoice formats are legally mandated with sequential numbering, VAT numbers, and mandatory fields. All major platforms support invoice automation through apps and plugins, often requiring zero custom code.
When to Use This Skill
- When customers request invoices after purchase and you are generating them manually
- When building B2B ecommerce where invoices are required before or after payment
- When you need to comply with EU VAT invoice requirements
- When integrating with accounting software (QuickBooks, Xero) that requires invoice records
- When subscription billing needs to generate invoices for each billing cycle
- When you need branded, professional PDFs rather than a payment processor's default invoice styling
Core Instructions
Step 1: Determine your platform and choose the right invoice tool
| Platform | Recommended Tool | Notes |
|---|---|---|
| Shopify | Order Printer Pro or Sufio (Shopify App Store) | Shopify has no native invoice PDF; Order Printer Pro is the most widely used free option; Sufio adds EU VAT compliance, accounting sync, and automated sending |
| WooCommerce | WooCommerce PDF Invoices & Packing Slips (free) or WooCommerce Germanized (EU compliance) | The free plugin handles standard invoice PDFs; Germanized adds legally compliant German/EU invoice formats |
| BigCommerce | Order Confirmation PDF (built-in) + Sufio or Invoice Ninja via API | BigCommerce sends a default order confirmation; Sufio adds branded PDFs with full EU VAT support |
| Stripe-based stores | Stripe Invoicing (built-in) | Stripe generates, sends, and tracks payment of invoices automatically; ideal for B2B and subscription billing |
| Custom / Headless | Stripe Invoicing API or Docspring / PDFMonkey for custom PDF generation | Stripe Invoicing handles the full lifecycle including dunning; PDF APIs handle custom designs |
Step 2: Set up automated invoice generation
---
Shopify
Option A: Order Printer Pro (free, basic)
1. Install Order Printer Pro from the Shopify App Store 2. Go to Apps → Order Printer Pro → Templates and customize the invoice HTML template with your logo, colors, and footer text 3. Under Settings, configure auto-printing triggers — when an order is fulfilled, the app can automatically email the invoice PDF to the customer 4. For EU VAT invoices: the app supports adding VAT numbers and compliant formatting; enable this under Settings → Tax settings
Option B: Sufio (recommended for B2B and EU VAT compliance)
1. Install Sufio from the Shopify App Store (paid, ~$19/month starting) 2. Go to Sufio → Settings → Document templates and upload your logo; customize fonts, colors, and layout 3. Under Sufio → Settings → Automation, configure when invoices are created and sent:
- Trigger: Order paid or Order fulfilled
- Action: Generate PDF and email to customer automatically
4. For EU VAT: go to Sufio → Settings → Tax settings and enable VAT invoice mode — Sufio adds the required fields (sequential number, seller/buyer VAT numbers, tax breakdown per line) 5. Connect to accounting: go to Sufio → Integrations and connect QuickBooks Online or Xero — invoices sync automatically
WooCommerce
Option A: WooCommerce PDF Invoices & Packing Slips (free)
1. Install WooCommerce PDF Invoices & Packing Slips from WordPress.org (by WP Overnight — the most popular option with 500,000+ installs) 2. Go to WooCommerce → PDF Invoices → Documents → Invoice and configure:
- Enable invoices for: new orders, processing, completed
- Upload your company logo
- Set invoice number format (e.g., year prefix: 2026-0001)
- Add company details (name, address, VAT number)
3. Under General, enable Attach to order confirmation email — invoices will be emailed automatically on order status change 4. For sequential numbering (required for EU VAT): go to Invoice → Number and enable the sequential counter
Option B: WooCommerce Germanized (EU VAT legal compliance)
1. Install WooCommerce Germanized — this plugin adds full German/EU legal compliance including legally required invoice elements 2. Configure your seller VAT number under WooCommerce → Germanized → General → VAT ID 3. Invoice settings are under WooCommerce → Germanized → Invoices — configure numbering, format, and automation triggers
Sync to accounting: 1. Install WooCommerce QuickBooks Online or WooCommerce Xero from the WooCommerce Marketplace 2. Orders and invoices sync automatically to your accounting system
BigCommerce
1. BigCommerce sends an order confirmation email by default — this serves as a basic invoice for B2C 2. For branded PDF invoices: install Sufio from the BigCommerce App Marketplace (same setup as Shopify above) 3. For custom invoice templates: go to Marketing → Email Templates → Order Confirmation and customize the default email template 4. For B2B invoice management: install Apruve or Balance from the App Marketplace — these handle net-terms invoicing with automated payment collection
---
Custom / Headless
Option A: Stripe Invoicing (recommended for B2B)
Stripe Invoicing handles the complete lifecycle — creation, PDF generation, customer emailing, payment tracking, and dunning for unpaid invoices:
// Create and send an invoice via Stripe Invoicing
const invoice = await stripe.invoices.create({
customer: stripeCustomerId,
collection_method: 'send_invoice',
days_until_due: 30,
metadata: { order_id: orderId },
custom_fields: [
{ name: 'PO Number', value: poNumber },
{ name: 'Your VAT Number', value: buyerVatNumber },
],
footer: 'Thank you for your business.',
});
// Add line items
for (const item of order.lineItems) {
await stripe.invoiceItems.create({
customer: stripeCustomerId,
invoice: invoice.id,
amount: Math.round(item.total * 100), // cents
currency: 'usd',
description: item.description,
tax_rates: [stripeTaxRateId], // if using Stripe Tax
});
}
// Finalize and send — Stripe generates PDF and emails it automatically
await stripe.invoices.finalizeInvoice(invoice.id);
await stripe.invoices.sendInvoice(invoice.id);The customer receives a Stripe-hosted invoice page where they can pay by card, bank transfer, or other methods. Stripe handles dunning (unpaid invoice reminders) automatically via Billing → Settings → Invoice reminders.
Option B: PDF generation service (for custom branding)
If you need full design control over the PDF, use PDFMonkey or Docspring:
// Generate a branded PDF using PDFMonkey
const response = await fetch('https://api.pdfmonkey.io/api/v1/documents', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PDFMONKEY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
document: {
document_template_id: process.env.INVOICE_TEMPLATE_ID,
status: 'pending',
payload: {
invoice_number: invoiceNumber,
issue_date: new Date().toISOString().split('T')[0],
due_date: dueDateString,
seller: { name: 'Your Company', address: sellerAddress, vat_number: sellerVat },
buyer: { name: customer.company_name, address: billingAddress, vat_number: buyerVat },
line_items: lineItems,
subtotal: order.subtotal,
tax_amount: order.taxAmount,
total: order.total,
},
},
}),
});
const { document } = await response.json();
// Poll for document.status === 'success', then retrieve document.download_urlStep 3: Ensure EU VAT invoice compliance
EU VAT invoices require these mandatory fields (check each is present in your template):
1. Sequential invoice number (no gaps) 2. Invoice date 3. Seller name, address, and VAT registration number 4. Buyer name and address; buyer VAT number (for B2B cross-border within EU) 5. Description of goods or services 6. Unit price, quantity, and line total per item 7. VAT rate and VAT amount per line 8. Total amount excluding VAT 9. Total VAT amount 10. Total amount including VAT
Sufio and WooCommerce Germanized both handle these requirements automatically.
Best Practices
- Use sequential numbers with no gaps for VAT-registered businesses — many tax authorities require sequential numbering; UUIDs are not compliant
- Snapshot customer and seller data at invoice creation — if the customer changes their address later, the invoice must reflect the address at the time of issue
- Store invoices immutably — never edit a sent invoice; issue a credit note and a replacement invoice for corrections
- Include a payment link prominently — bank details, ACH routing, or a pay-now link should be the most visible element on B2B invoices
- Automate sync to accounting — use Sufio's built-in QuickBooks/Xero sync or a tool like A2X to avoid manual data entry
Common Pitfalls
| Problem | Solution |
|---|---|
| Invoice numbers are not sequential (gaps after failed orders) | Use apps like Sufio or WooCommerce PDF Invoices which maintain their own sequential counter independent of order status |
| Duplicate invoices for the same order | All recommended apps handle idempotency — they check whether an invoice already exists for the order before creating a new one |
| EU VAT invoice missing mandatory fields | Use Sufio (Shopify/BigCommerce), WooCommerce Germanized (WooCommerce), or Stripe Invoicing with custom_fields for the VAT numbers |
| PDF too large for email attachment | Invoice apps use efficient PDF rendering; issues typically occur with large image assets in the template — compress your logo |
| QuickBooks/Xero sync fails silently | Check the integration logs in your invoice app; most apps have a retry mechanism and will alert you on sync failures |
| Customer replies to invoice email but gets no response | Configure invoice delivery from a monitored billing@yourdomain.com address, not a noreply@ address |
Related Skills
- @accounts-receivable-automation
- @tax-compliance-automation
- @payment-terms-optimization
- @stripe-integration
- @subscription-billing
{
"context": "Tests whether the agent implements idempotency (checking for existing invoice before creating), snapshots buyer/seller data on creation, correctly determines EU VAT invoice type, makes QuickBooks sync non-blocking with error handling, stores QB document ID in metadata, uses node-quickbooks package, and uses a billing@ sender address for invoice emails.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Idempotency check",
"max_score": 10,
"description": "generateAndSendInvoice checks for an existing non-void invoice for the same order_id before creating a new one, and returns the existing invoice if found"
},
{
"name": "Seller data snapshot",
"max_score": 8,
"description": "The invoice record creation includes seller_name, seller_address, and seller_tax_id fields populated from a company/settings source (not left null or omitted)"
},
{
"name": "Buyer data snapshot",
"max_score": 8,
"description": "The invoice record creation includes buyer_name, buyer_address, and buyer_tax_id (VAT number) fields populated from the customer/order source"
},
{
"name": "EU VAT type detection",
"max_score": 10,
"description": "Invoice type is determined by checking whether the customer's country is in a list of EU countries AND whether the seller is VAT-registered (not just one condition alone)"
},
{
"name": "EU_COUNTRIES constant",
"max_score": 5,
"description": "A named constant (e.g. EU_COUNTRIES) holds the array of EU country codes used for VAT detection"
},
{
"name": "Non-blocking accounting sync",
"max_score": 12,
"description": "The call to pushToAccounting (or equivalent) uses .catch() or try/catch such that a rejection/error does NOT propagate and reject the overall generateAndSendInvoice promise"
},
{
"name": "Sync failure logged",
"max_score": 7,
"description": "When the accounting sync fails, the error is logged (console.error or equivalent) with at least the invoice ID and error message — it is not silently swallowed"
},
{
"name": "node-quickbooks package",
"max_score": 10,
"description": "accounting-sync.js imports QuickBooks from 'node-quickbooks' (not a different QuickBooks client or a generic HTTP client)"
},
{
"name": "QB doc ID stored in metadata",
"max_score": 10,
"description": "After a successful QuickBooks sync, the QuickBooks invoice ID (from the API response) is saved into the invoice's metadata field (e.g. as qb_invoice_id)"
},
{
"name": "Billing sender address",
"max_score": 10,
"description": "The invoice email sender (From or Reply-To) is configured with a 'billing@' address — NOT a 'noreply@' address"
},
{
"name": "Invoice immutability noted",
"max_score": 10,
"description": "The code or comments indicate that sent invoices should not be edited and that corrections require a credit note (e.g. a comment, a guard, or a test case)"
}
]
}
Invoice Generation Orchestrator
Problem/Feature Description
Meridian Digital sells SaaS subscriptions and physical goods to both US businesses and EU companies. Their order system fires an event for every completed order, but invoice generation sometimes crashes mid-way (network error, database timeout), causing the same order to trigger invoice generation twice and resulting in duplicate invoices — one of which is usually incomplete. Additionally, the finance team discovered that some invoices sent to German and French B2B buyers are missing the buyer's VAT number and the correct invoice type, causing those customers to reject them for their own VAT reclaim.
Meridian also needs QuickBooks to stay in sync with every invoice so the accounting team doesn't have to manually enter them. However, QuickBooks connectivity is unreliable, and when sync fails it currently crashes the entire invoice creation flow and leaves orders without any invoice at all.
Your task is to implement the generateAndSendInvoice(order) orchestrator function in JavaScript/Node.js. The function must handle the full invoice lifecycle: safe handling of repeated calls for the same order, determining the correct invoice type based on the customer's region, persisting all relevant data, synchronising with the accounting system without letting connectivity issues break the flow, and emailing the invoice to the customer.
Output Specification
Produce the following files:
src/invoice-service.js— The orchestrator module. It may import helper functions from sibling modules (you can stub those as needed). Document the key design decisions in inline comments.src/accounting-sync.js— The QuickBooks accounting sync module.src/invoice-email.js— A stub email sender module that logs what it would send.package.json— Declares required dependencies.src/invoice-service.test.js— Tests that document the key behaviours: handling of repeated calls for the same order, EU vs non-EU invoice type selection, and accounting sync failure handling.
{
"context": "Tests whether the agent uses Puppeteer for PDF rendering, Handlebars for templating, correct Puppeteer launch configuration, proper Handlebars helper registration, tax breakdown computation, and prominent payment instructions in the template.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Uses Puppeteer",
"max_score": 10,
"description": "The renderer imports and uses puppeteer (not another PDF library like pdfkit, jsPDF, or wkhtmltopdf)"
},
{
"name": "Uses Handlebars",
"max_score": 10,
"description": "The renderer imports and uses handlebars (not another templating engine like ejs, pug, or nunjucks)"
},
{
"name": "Puppeteer sandbox args",
"max_score": 8,
"description": "Puppeteer is launched with both '--no-sandbox' and '--disable-setuid-sandbox' in the args array"
},
{
"name": "networkidle0 wait",
"max_score": 8,
"description": "page.setContent() is called with { waitUntil: 'networkidle0' } (not 'load', 'domcontentloaded', or 'networkidle2')"
},
{
"name": "printBackground enabled",
"max_score": 7,
"description": "page.pdf() is called with printBackground: true"
},
{
"name": "20mm margins",
"max_score": 7,
"description": "page.pdf() sets margin with top, right, bottom, and left all equal to '20mm'"
},
{
"name": "Paper size from template",
"max_score": 7,
"description": "The paper size (format) passed to page.pdf() comes from the template object (e.g. template.paper_size) rather than being hardcoded"
},
{
"name": "formatCurrency helper",
"max_score": 8,
"description": "A Handlebars helper named 'formatCurrency' is registered using Intl.NumberFormat with style: 'currency'"
},
{
"name": "formatDate helper",
"max_score": 7,
"description": "A Handlebars helper named 'formatDate' is registered using Intl.DateTimeFormat"
},
{
"name": "multiply helper",
"max_score": 5,
"description": "A Handlebars helper named 'multiply' is registered"
},
{
"name": "Tax breakdown computation",
"max_score": 10,
"description": "A function computes a tax breakdown grouped by tax rate/name across line items (aggregating taxable_amount and tax_amount per group), and this breakdown is passed to the template"
},
{
"name": "Payment instructions prominent",
"max_score": 8,
"description": "The invoice HTML template includes a section for payment instructions (bank details, ACH routing, or pay-now link) that is visually prominent (e.g. has a distinct CSS class, heading, or is placed in the invoice footer/summary area)"
},
{
"name": "Tax breakdown in template",
"max_score": 5,
"description": "The invoice HTML template renders the tax breakdown (iterating over tax groups and showing name and amount), not just a single tax total"
}
]
}
Invoice PDF Renderer Service
Problem/Feature Description
Acme Supplies is a B2B wholesale distributor that needs to generate professional PDF invoices for every completed order. Their current system emails plain-text order confirmations, but enterprise customers are increasingly requiring proper invoices — complete with branded headers, itemised line details, per-line tax information, and all the information needed for customers to process payment or submit expense claims.
Your task is to build a self-contained invoice PDF renderer module in JavaScript/Node.js. The renderer must accept invoice data (including line items, each with its own tax rate and tax amount) and a template definition (with branding configuration like colors and paper size), and produce a PDF buffer. The generated PDF must be suitable for sending directly to customers and should handle all the financial details correctly.
The finished module should be production-ready, with a working example that can be executed to verify the output.
Output Specification
Produce the following files:
src/pdf-renderer.js— The renderer module implementing the full PDF generation logic.src/invoice-template.html— A complete Handlebars HTML template for an invoice that a customer could actually receive. The template should handle all the invoice fields and produce a visually complete, professional document.example/generate-invoice.js— A standalone script that imports the renderer, defines sample invoice data with at least two line items carrying different tax rates, and calls the renderer to produce a PDF file saved toexample/output-invoice.pdf. The script should print the resulting PDF file size to stdout.package.json— Declares the required dependencies.
The script in example/generate-invoice.js should be runnable with node example/generate-invoice.js after npm install. Clean up the PDF file if it is larger than 50 MB (it should not be).
{
"context": "Tests whether the agent implements sequential invoice numbering using PostgreSQL advisory locks inside a database transaction, produces the correct PREFIX-YEAR-NNNNNN format with 6-digit zero-padding, excludes proforma invoices from the main series, and implements credit notes with a separate CN- prefix series.",
"type": "weighted_checklist",
"checklist": [
{
"name": "Advisory lock used",
"max_score": 15,
"description": "The generateInvoiceNumber function executes a PostgreSQL advisory lock — specifically calls pg_advisory_xact_lock (not a row-level lock, application mutex, or other mechanism)"
},
{
"name": "Transaction wrapping",
"max_score": 12,
"description": "The advisory lock and count query are both inside a database transaction (e.g. db.$transaction or equivalent), not called sequentially outside a transaction"
},
{
"name": "6-digit zero-padded sequence",
"max_score": 10,
"description": "The sequence number is zero-padded to 6 digits (e.g. padStart(6, '0')) producing values like 000001, 000042"
},
{
"name": "PREFIX-YEAR-NNNNNN format",
"max_score": 10,
"description": "The returned invoice number follows the pattern {prefix}-{year}-{paddedSequence} (e.g. INV-2026-000001)"
},
{
"name": "Proforma excluded from series",
"max_score": 15,
"description": "When counting existing invoices to determine the next sequence number, proforma invoice types are excluded from the count (filter: invoice_type not equal to 'proforma')"
},
{
"name": "Credit note separate series",
"max_score": 15,
"description": "generateCreditNoteNumber produces numbers with the 'CN-' prefix (e.g. CN-2026-000001), counting only existing credit_note type invoices — NOT mixed with regular invoices"
},
{
"name": "No-gaps explanation",
"max_score": 8,
"description": "The code includes a comment or the README includes a section explaining why the advisory lock prevents gaps (not just that it prevents duplicates)"
},
{
"name": "count + 1 sequence logic",
"max_score": 15,
"description": "The sequence number is derived by counting existing invoices with the same prefix-year pattern and adding 1 (not using a separate counter table or application-level state)"
}
]
}
Invoice Number Generator
Problem/Feature Description
Nexus Commerce operates across multiple EU countries and is required by tax authorities to produce invoices with strictly sequential, gap-free numbering — any gap in the sequence can trigger an audit and result in fines. The business also issues proforma invoices (quotes sent before payment) and credit notes (partial or full refunds), which must each belong to their own independent series to avoid confusion with the legal invoices.
The company runs the billing service on multiple application servers simultaneously. In the past, a naive JavaScript counter caused duplicate invoice numbers when two orders were completed at the same moment, and a junior developer's fix (using UUIDs) was rejected by the tax authority as non-compliant.
Your task is to implement the invoice number generation module in JavaScript/Node.js using Prisma as the ORM against a PostgreSQL database. The module must handle concurrent requests safely, produce the correct number formats, and keep the different invoice series completely separate.
Output Specification
Produce the following files:
src/number-generator.js— The number generator module with at minimum two exported functions:generateInvoiceNumber({ year, prefix, locale })— generates the next number in the main invoice seriesgenerateCreditNoteNumber(originalInvoiceNumber)— generates the next credit note number
src/number-generator.test.js— Unit/integration tests (using any test framework) that document the expected behaviour, covering the number format, series separation, and concurrency safety.
package.json— Declares required dependencies.
Write a README.md section (or a comment block at the top of number-generator.js) that explains the concurrency strategy used and why it prevents gaps.
{
"name": "finsi/invoice-generation-automation",
"version": "0.1.0",
"summary": "Generate professional invoices automatically with custom branding, payment terms, line item details, tax breakdowns, and integration with accounting systems",
"skills": {
"invoice-generation-automation": {
"path": "SKILL.md"
}
}
}