Skip to content
In this section

Invoices

An invoice's lifecycle, numbering and amounts, immutable once issued.

A billing invoice is an immutable, numbered document. The relational fields you see in responses (totals, dates, status) mirror a frozen, schema-valid payload snapshotted at issue time; the PDF renders from that snapshot.

Lifecycle

draft → issued → sent → paid, with overdue for a sent document still unpaid past its due date, and three corrective exits:

  • voided — the document was cancelled before money moved (voidedAt, voidReason).
  • written off — collection was abandoned (writtenOffAt, writeOffReason).
  • credit note — a separate document (invoiceType: "credit_note") naming the original in originalInvoiceNumber.

paidVia records how a paid document settled: payment_link (the card rail — either the buyer visiting the hosted page, or an off-session charge on their saved card when the seller has auto-collection enabled), bank_transfer (a deposit on the collection account named on the document) or credit (stored credit covered it in full at issue).

A document can therefore reach paid without you doing anything, and can appear on GET /invoices without anyone creating it: whether terms and metered usage are invoiced on a schedule, and whether saved cards are charged off-session, are platform switches. See Sandbox & testing for the switches themselves.

Numbering

Every issued document carries TWO numbers, and they are not interchangeable.

invoiceNumber (UK2607AB-2607AAC) is the document's identity: unique across every Fynex invoice family, allocated from the shared per-(agreement, month) sequence, and also the bank payment reference — it is the only string a buyer may quote on a transfer, and it is what bankTransfer.paymentDescription returns.

customerDocumentNumber (0000042) is the document's position in that customer's own series: cumulative for the life of the (seller, customer) pair, never reset, and counted independently for each customer. Credit notes take the next position like any other document, and a voided document keeps the one it had. It is a convenience reference printed as "Your document no." — unique only within the pair, so it is never a lookup key and never a payment reference. Absent on documents issued before the series existed; those are not backfilled.

Numbering

An invoice number is <agreement>-<YYMM><order>: your agreement number, a dash, the issue month as YYMM, and a three-letter order within that month (AAA, AAB, …) — for example UK2607AA-2608AAB is the second document issued in August 2026 under agreement UK2607AA. The series is allocated inside the issuing transaction, so it is gapless per month, and it is shared with top-up invoices so the two document families can never collide. Numbers are what corrects and originalInvoiceNumber reference, so store them verbatim — do not parse meaning out of the order suffix.

customerName and customerEmail carry who the document was addressed to at issue — taken from the frozen payload, so a customer later renaming themselves does not rewrite an issued legal record. They are returned by the single-invoice read and by send, and omitted from list rows.

Endpoints

  • GET /billing-api/v1/invoices — list, newest first, paged with cursor/limit. Filters: contractId, sellerCustomerId, status, invoiceType (standard, credit_note, simplified, modified), origin (recurring, usage, milestone, project, one_time, adhoc, marketplace; subscription is a deprecated alias of recurring), corrects (credit notes against an invoice number), issuedFrom/issuedTo (half-open date range).
  • POST /billing-api/v1/invoices — compose, number and (by default) send a document in one call, behind a required Idempotency-Key. It is issued and immutable the moment the call answers 201; the same key replays the document with 200 and no link, and a key whose request differs in its contract, customer, currency, invoiceType, dueDate, net line total or line count answers 422 naming the field. There are no drafts on this API: send explicit lines with unitPriceMinor. invoiceType accepts standard (the default), simplified and modified; credit_note is refused with 400 — a correction is raised against the document it corrects, which this request cannot express, and there is no originalInvoiceNumber field on it. Correct a mistake in the dashboard.
  • GET /billing-api/v1/invoices/{invoiceId} — one invoice with its lines.
  • GET /billing-api/v1/invoices/{invoiceId}/pdf — the rendered PDF.
  • POST /billing-api/v1/invoices/{invoiceId}/send — materialize the collection instrument: creates the invoice's hosted payment link and returns the invoice together with paymentLinkUrl. It emails your customer whenever the document carries a buyer email; there is no per-request suppression in v1, so the first call is customer-facing. The invoice is itself the collection anchor, so retries and simultaneous calls return the one existing link and do not send another email — no idempotency header is needed. Not applicable (422) to bank-transfer documents, to documents outside issued/sent/overdue (a draft, or one already paid, voided or written_off), or to documents with nothing left to collect.

Amounts

grandTotalMinor is the legal document total. collectibleMinor is what collection asks the customer for: the grand total less creditAppliedMinor (stored credit drawn down at issue).

creditSettledMinor reports only the part discharged by that stored credit — it is not a payment total, and a card- or transfer-paid invoice reports 0. Neither amount changes when the invoice is paid: status and paidVia are what tell you the outcome.

outstandingMinor is the one to age in an AR report. collectibleMinor is frozen at issue and stays there, so it keeps asking for the full amount after a credit note, a write-off or any other adjustment; outstandingMinor is derived from the adjustment ledger on every read and reports what is genuinely still owed (0 for a voided document). It is omitted when the adjustment ledger is unavailable — absence means unknown, not 0.