billfold-invoice-link
v0.1.0
Published
Build a whole prefilled invoice as a shareable URL for Billfold — zero dependencies, no account, no server. Opening the link launches Billfold with the invoice ready.
Maintainers
Readme
billfold-invoice-link
Build a whole prefilled invoice as a shareable URL for Billfold — the local-first invoice generator. Opening the link launches Billfold with the invoice ready to review and export. No account, no API call, nothing uploaded — the invoice travels in the link itself.
- Zero dependencies, ~2 kB, works in Node and the browser.
- Typed (ships
index.d.ts). - Round-trips:
buildInvoiceLink⇄parseInvoiceLink.
npm install billfold-invoice-linkUse
const { buildInvoiceLink } = require('billfold-invoice-link');
const url = buildInvoiceLink({
currency: 'USD',
business: 'Jordan Rivera Design',
client: 'Acme Co',
invoiceNumber: 'INV-0042',
notes: 'Payment due in 14 days',
items: [
{ description: 'Landing page design', quantity: 1, rate: 1800 },
{ description: 'Revisions', quantity: 3, rate: 120 },
],
});
// https://billfold.io/app/?cur=USD&biz=Jordan+Rivera+Design&to=Acme+Co&no=INV-0042¬es=...&item=Landing+page+design|1|1800&item=Revisions|3|120Send that link to a client, drop it in an email, or generate one per customer from your own app or spreadsheet. When it opens, Billfold fills the invoice in — entirely in the browser.
A CIS subcontractor invoice (negative line)
Rates can be negative, which is how a CIS deduction line is expressed:
buildInvoiceLink({
currency: 'GBP',
items: [
{ description: 'Labour (subject to CIS)', rate: 1000 },
{ description: 'Materials', rate: 300 },
{ description: 'Less: CIS deduction @ 20%', rate: -200 },
],
});Parse one back
const { parseInvoiceLink } = require('billfold-invoice-link');
parseInvoiceLink('https://billfold.io/app/?cur=USD&item=Consulting|2|150');
// { baseUrl: 'https://billfold.io/app/', currency: 'USD', items: [ { description: 'Consulting', quantity: 2, rate: 150 } ] }API
buildInvoiceLink(options?) → string
| Option | Type | Notes |
|---|---|---|
| type | 'invoice' \| 'quote' \| 'estimate' | Defaults to invoice. |
| currency | string | e.g. 'USD', 'GBP', 'EUR'. |
| business / businessMeta | string | Your name and a line under it (address, tax id). |
| client / clientMeta | string | Bill-to name and a line under it. |
| invoiceNumber | string | |
| notes | string | Free text / payment terms. |
| payLink | string | A "Pay" button URL. Must be https://. |
| tax | number | Percent. |
| discount / discountType | number / 'pct' \| 'flat' | |
| items | Array<{ description, quantity?, rate? } \| string> | quantity defaults to 1, rate to 0. description cannot contain \|. |
| baseUrl | string | Defaults to https://billfold.io/app/. |
Throws TypeError on an invalid type, a non-https payLink, a \| in a description, or a non-numeric tax/discount.
parseInvoiceLink(url) → options
The inverse. Useful for tests, or to read a link a user pasted.
How it works
Billfold has no backend. A deep-link is just its documented URL API: query params for the header fields, and one repeatable item=description|quantity|rate per line. This package assembles (and reads) that URL correctly — encoding, the | field rule, negative rates, and the https-only pay link — so you don't hand-build query strings. Nothing here calls a network; it's pure string work.
Sharing a filled, view-only invoice (the whole document encoded in the URL #hash) is a separate Billfold feature done inside the app and is out of scope for this builder.
License
MIT © Billfold
