Lifecycle first
Draft, sent, viewed, overdue, paid, and void states define what the user can do next.
A production billing workspace for freelancers and small businesses—covering document creation, invoice lifecycle, client management, expenses, payments, reporting, and the operational details between them.

Small businesses often split invoices, payments, client records, expenses, and reporting across several tools. Every handoff adds another place for a document state, balance, or customer detail to drift out of sync.
InvoiceBirds brings those jobs into a single operating model. A document can move from draft to delivery and payment while the surrounding client and expense context remains close at hand.
My work focused on making that depth feel calm: reusable document controls, clear lifecycle states, consistent navigation, and responsive surfaces that preserve the same workflow away from the desktop.
Feb — Sep 2025
Full-Stack Contractor
The interface is organised around three connected jobs. Each can stand alone, but the product becomes more useful when information moves cleanly between them.
Build invoices and business documents through modular controls with a live visual preview.
Track document status, clients, expenses, and payment activity without losing the surrounding context.
Bring billing and spending into a shared reporting model designed for fast operational decisions.
These are current product screens, not presentation mockups. The captions follow the work visible in each surface and explain how the product is structured.

Document workspace / 01
Modular controls sit beside a live document preview, keeping content, styling, payment options, and export actions inside one focused workspace.

Invoice lifecycle / 02
Search, filters, status groups, exports, and document actions turn the list into a working queue rather than a passive archive.

Expense operations / 03
Expense profiles group activity by team, person, department, or project, making the operational model visible without burying it in settings.
Billing workflow
The interface stays calm because document, money, and operational states are explicit underneath it.
Draft, sent, viewed, overdue, paid, and void states define what the user can do next.
Currency, tax, discount, and payment metadata remain attached to the document that created them.
Billing activity sits beside the customer and spending context needed to understand the business.
Validation, permissions, reconciliation, and failure handling ship with the visible product surface.
Mobile is not a scaled-down poster of the desktop app. Navigation, document controls, and list actions are reflowed around the task that matters in the moment.

Public product

Document builder

Invoice lifecycle
System architecture
The stack separates experience, application rules, durable data, and payment providers without fragmenting the user journey.
Responsive document, client, expense, and reporting surfaces share reusable interaction patterns.
Billing rules, document transitions, permissions, and integrations live behind explicit modules.
Relational records preserve customers, documents, line items, expenses, and historical state.
Checkout, webhooks, manual payments, and invoice state converge on one auditable payment record.
Engineering Challenges
Solution · Standardised on integer-cents internally, FX conversion at write-time only, snapshotted to invoice metadata so the historical record never re-quotes. UI formatting via Intl.NumberFormat per locale.
Outcome · An issued document retains the totals and exchange context it had at issue time instead of changing with a later rate.
Solution · Idempotency keys on every webhook, payment events appended to a per-invoice ledger (not overwritten), with manual mark-paid for off-Stripe payments. Background reconciler reconciles Stripe + manual + invoice state every N minutes.
Outcome · Single source of truth on invoice status — no conflicting paid/unpaid displays across screens.
Solution · Extracted a primitives layer (line-item table, client picker, tax/discount calculator, signature block) that each document type composes. Validation via Zod schema per document type.
Outcome · Document types share the same line-item, client, tax, discount, and signature behaviours instead of drifting into separate form systems.
I take on senior contract work across modern full-stack stacks with payment, multi-currency, and integration depth.