Invoices are the canonical billing artifact in OpenSettle. Subscriptions generate them automatically; you can also create one-off invoices for services, retainers, or migrations. Every invoice has a stable URL, a PDF, and a public pay-link your customer can use without leaving their wallet.
const invoice = await os.invoices.create({
customer: "cus_9fX0a2E1",
currency: "USD",
settlement: { chain: "base", token: "USDC" },
due_date: "2026-05-02",
payment_terms: "net_14",
line_items: [
{ description: "Implementation, April 2026", quantity: 1, unit_amount: 4800.00 },
{ description: "Hosting credits", quantity: 200, unit_amount: 0.50 },
],
memo: "Thanks for working with us.",
footer: "Tax ID: 88-1932041",
});
await os.invoices.send(invoice.id); // emails the customer + creates pay-linkInvoices move through the following states. Transitions emit invoice.* webhooks; terminal states are paid and void.
draft — created but not yet sent. Editable. Not visible to the customer.open — sent. Pay-link is live. Reminders fire on the cadence you set.paid — on-chain settlement confirmed. Receipt emailed automatically.past_due — due date passed without payment. Still payable.void — canceled. Pay-link returns 410. Audit trail preserved.Pass any of due_on_receipt, net_7, net_14, net_30, net_60, or explicit due_date. For early-payment discounts and late fees, configure a terms_policy on the customer or invoice — these are computed and shown on the hosted invoice automatically.
Daily exports land in your dashboard at 00:30 UTC and contain every invoice with a state change in the prior 24 hours, plus the on-chain tx hash for any paid transition. Export on-demand via the API or CLI:
opensettle invoices export \
--from 2026-04-01 --to 2026-04-17 \
--format csv > april.csvSee Reconciliation for the column schema and accounting-system mappings.