Skip to main content
Early access — new tools and guides added regularly
🟡 AI-Assisted Business Ops — Guide 6 of 10
View track
>_ claude codeIntermediate30 min

Automated Invoice System

Build an invoicing system with customisable templates, PDF generation, automated payment reminders, and overdue tracking — everything a small business needs to get paid on time.

What you will build
A complete invoicing system with PDF generation, email delivery, and payment tracking

Designing the invoice data model

An invoice is a structured document with specific legal requirements that vary by jurisdiction. At minimum, every invoice needs: a unique invoice number, the seller's details (name, address, tax ID), the buyer's details, a date of issue, line items (description, quantity, unit price, total), subtotal, tax calculation, total due, payment terms, and payment methods. Ask Claude Code: Create a new Node.js project for an invoice system. Set up TypeScript. Create types at src/types.ts for Business (name, address, email, phone, tax_id, logo_url, bank_details with account name, sort code, account number), Client (id, name, email, address, contact_person, payment_terms_days), LineItem (description, quantity, unit_price, tax_rate as a decimal, amount), Invoice (id, invoice_number as a formatted string like INV-2024-001, business as Business, client as Client, items as LineItem array, subtotal, tax_total, total, currency, status as draft or sent or paid or overdue or cancelled, issue_date, due_date, paid_date optional, notes optional), and PaymentReminder (invoice_id, sent_at, type as upcoming or due or overdue). Create sample data at src/data.ts with your business details and 3 sample clients with different payment terms (14 days, 30 days, 45 days). Create a utility at src/invoice-utils.ts with functions to: generate the next invoice number sequentially, calculate line item amounts with tax, calculate invoice totals, determine invoice status based on dates and payment records, and format currency. Test each function with sample data to verify calculations are correct, especially tax rounding — always round to 2 decimal places after calculating each line item, not on the total.

PDF invoice generation

Invoices need to be delivered as professional PDF documents. Ask Claude Code: Set up PDF generation using the pdfkit library. Install pdfkit: npm install pdfkit @types/pdfkit. Create a PDF generator at src/pdf-generator.ts that takes an Invoice object and produces a professional PDF. The layout should include: your business logo and details in the top left, the invoice number and date in the top right, the client details below the business details, a table of line items with columns for description, quantity, unit price, tax rate, and amount, a totals section showing subtotal, tax by rate, and total due in bold, payment terms stating when payment is due, bank details for payment, and optional notes at the bottom. Use a clean professional design: consistent font sizes (headings at 14pt, body at 10pt, small text at 8pt), a single accent colour for headings and the total row, thin horizontal rules between sections, and ample whitespace. Run the generator: npx ts-node src/generate-test-invoice.ts. Open the resulting PDF and verify it looks professional. Ask Claude Code: Add support for multiple invoice templates. Create a template system where templates are configuration objects defining colours, fonts, layout preferences, and which optional sections to include. Create three templates: Classic (formal, serif font, navy accents), Modern (sans-serif, coloured header bar, minimal lines), and Simple (black and white, maximum readability). The generator should accept a template parameter. Test all three templates and compare the output. Ask Claude Code: Add a credit note template that mirrors the invoice layout but clearly marks the document as a credit note with negative amounts. This is needed when you need to partially or fully refund an invoice.

Email delivery system

Invoices should be emailed directly to clients with the PDF attached. Ask Claude Code: Create an email delivery system at src/email.ts using Resend. Build an HTML email template that accompanies the invoice PDF. The email should include: a professional greeting with the client contact's name, a brief message stating that invoice number INV-2024-001 for a specified amount is attached, the due date prominently displayed, a summary of what the invoice covers (first line item description as a preview), your payment details for quick reference, and a polite closing. Attach the PDF invoice to the email using Resend's attachment support — generate the PDF as a Buffer rather than writing to disk, then include it as an attachment with the filename matching the invoice number. Ask Claude Code: Create a send-invoice command that generates the PDF, sends the email, updates the invoice status from draft to sent, and logs the delivery. Run it: npx ts-node src/send-invoice.ts INV-2024-001. Verify the email arrives with the PDF attachment and that the invoice status is updated. For error handling, catch email delivery failures and retry once after 5 minutes. Log all delivery attempts with the status, timestamp, and any error messages. Ask Claude Code: Add a batch sending feature for sending multiple invoices at once. Accept an array of invoice IDs, generate and send each one with a 2-second delay between sends to respect rate limits. Show a progress report: Sent 3 of 5 invoices. Report any failures at the end with the invoice ID and error reason. Also create a preview mode that generates the PDF and opens it locally without sending the email — useful for reviewing invoices before delivery. Add a CC option to send a copy to yourself or to an accountant's email address.

Payment tracking and reconciliation

Once invoices are sent, you need to track which are paid and which are overdue. Ask Claude Code: Create a payment tracking system at src/payments.ts. Build functions to: record a payment against an invoice (amount, date, payment method, reference number), handle partial payments (update the outstanding balance, keep status as sent until fully paid), mark an invoice as paid when the total is covered, automatically flag invoices as overdue when the due date passes without full payment, and generate an accounts receivable aging report. The aging report should group outstanding invoices into buckets: current (not yet due), 1-30 days overdue, 31-60 days overdue, 61-90 days overdue, and over 90 days overdue. Show each bucket's total and list the individual invoices. This report is essential for cash flow management. Ask Claude Code: Create a reconciliation tool. Given a CSV export from your bank statement, match payments to invoices by amount and reference number. For each bank transaction, attempt to find a matching unpaid invoice. Show matched transactions, unmatched bank transactions (payments you received but cannot identify), and unmatched invoices (invoices that have not been paid). This semi-automated reconciliation saves hours compared to manual matching. Ask Claude Code: Build a dashboard at src/dashboard.ts that generates an HTML report showing: total invoiced this month, total received, total outstanding, overdue amount, the aging report as a visual chart, and a list of the 5 most overdue invoices. Open the HTML file in a browser for a visual overview of your invoicing health. Add a cash flow forecast that projects expected income based on outstanding invoices and their due dates, factoring in historical payment patterns (for example, if a client typically pays 10 days late, adjust the forecast accordingly).

Automated payment reminders

Chasing payments is unpleasant but necessary. Automation makes it systematic and removes the emotional burden. Ask Claude Code: Create a reminder system at src/reminders.ts. Build three email templates for different stages. Upcoming reminder (sent 3 days before due date): friendly heads-up that invoice INV-2024-001 for a specified amount is due on a specific date, with payment details for convenience. Due date reminder (sent on the due date): professional note that the invoice is due today, with an attached copy of the invoice and payment instructions. Overdue reminder (sent 7, 14, and 30 days after the due date): escalating firmness. The 7-day email is a gentle reminder. The 14-day email is firmer and asks if there is an issue with the invoice. The 30-day email mentions that continued non-payment will require further action. Each template should include the invoice number, amount, original due date, days overdue, and a link or attachment of the original invoice. Ask Claude Code: Create a reminder scheduler that runs daily. It checks all sent invoices, identifies which reminders should be sent based on the dates, checks which reminders have already been sent (to avoid duplicates), and sends the appropriate reminders. Log every reminder sent with the invoice ID, reminder type, and recipient. Run the scheduler: npx ts-node src/run-reminders.ts. It should report: Sent 2 upcoming reminders, 1 due date reminder, 0 overdue reminders. Ask Claude Code: Add a do-not-remind flag per client for situations where you are in active discussion about payment and automated reminders would be inappropriate. Add an escalation notification: when an invoice hits 30 days overdue and the final reminder has been sent, notify you (the business owner) with a summary so you can take manual action. Track reminder effectiveness: for invoices that were eventually paid, record how many days after each reminder type the payment came in. Over time this data shows which reminders are most effective.

Recurring invoices and subscription billing

Many businesses invoice the same clients regularly for the same services. Ask Claude Code: Add recurring invoice support. Create a RecurringInvoice type with fields for: client ID, line items (the same each period), frequency (weekly, monthly, quarterly, annually), next_issue_date, auto_send (boolean), and active status. Build a function that checks for recurring invoices due today, generates the invoice with the next sequential number, optionally sends it automatically if auto_send is true, and updates the next_issue_date based on the frequency. Create a setup flow: npx ts-node src/create-recurring.ts that interactively collects the client, items, and frequency, then saves the recurring invoice configuration. Ask Claude Code: Add invoice templates for common service packages. If you offer a monthly retainer for consulting at 2000 pounds, a monthly hosting fee at 50 pounds, or a quarterly review at 500 pounds, create templates that pre-fill the line items. Generating a new invoice from a template is a single command: npx ts-node src/invoice-from-template.ts monthly-retainer client-123. Ask Claude Code: Handle year-end accounting requirements. Create a script that generates a yearly summary showing: total invoiced per client, total tax collected, total received versus outstanding, and a monthly revenue breakdown. Export as both JSON for programmatic use and CSV for import into accounting software. Create a tax report that shows total VAT collected per quarter for VAT returns. These reports save significant time during tax season and reduce the chance of errors in manual calculations. Also create a client statement generator — a PDF showing all invoices for a specific client in a date range with their payment status, useful when a client disputes their outstanding balance.

Multi-currency and internationalisation

If you work with international clients, you need to handle multiple currencies. Ask Claude Code: Add multi-currency support to the invoice system. Update the Invoice type to include a currency code (GBP, USD, EUR, etc.) and an exchange rate to your base currency. Create a currency utility at src/currency.ts that formats amounts according to the currency's conventions (GBP uses a pound sign and 2 decimal places, JPY uses a yen sign and 0 decimal places), fetches current exchange rates from a free API like exchangerate-api.com, converts between currencies using the stored exchange rate, and calculates the base currency equivalent for reporting. Update the PDF generator to display the correct currency symbol and format. Update all reports to show amounts in both the invoice currency and the base currency equivalent. Ask Claude Code: Add per-country invoice requirements. In the UK, invoices must show the VAT number and VAT amount. In the EU, reverse charge mechanism invoices need specific wording. In the US, sales tax varies by state. Create a country configuration that defines the required fields and tax rules for each jurisdiction. The invoice generator should validate that all country-required fields are present before generating the PDF. Ask Claude Code: Create an end-to-end test that generates invoices in GBP, USD, and EUR, sends them via email, records payments in their original currencies, and generates a reconciliation report showing all amounts in the base currency. Verify that the exchange rate conversions are consistent — use the rate from the invoice date, not the payment date, for accounting consistency. Test edge cases: what happens when an exchange rate API is unavailable? Fall back to the last known rate and flag the invoice for manual review. This multi-currency capability is essential for any business operating internationally and saves the cost of dedicated accounting software for small operations.

Related Lesson

Business Automation

This guide is hands-on and practical. The full curriculum covers the conceptual foundations in depth with structured lessons and quizzes.

Go to lesson