Invoices

Payment-time combination: merge two or more open, unpaid invoices belonging to the same client into one new invoice. Only bills past the estimate→invoice approval gate qualify — the merge copies their lines (dispense links carried over; dispensing and approval are untouched), re-runs the price rule engine against the combined line set, and archives the sources as Superseded with `mergedIntoInvoiceId` pointing at the new bill.

Changed on
post/Invoices/merge

Request

Request body

invoiceIdsstring[]
carryOrderDiscountFromInvoiceIdstring nullable

Optional: the id of one of the merged source invoices whose order-level discount code should be carried onto the combined bill (recalculated against the merged subtotal). Null carries no order-level discount forward. Only one is supported — precise per-source distribution across lines is a follow-up.

Response

Created

idstring
invoiceNumberstring
clientIdstring nullable
clientNamestring nullable
patientIdstring nullable
patientNamestring nullable
appointmentIdstring nullable
providerModestring
invoiceProviderIdstring nullable
statusstring
hasUnresolvedPaymentboolean

A payment here is still open: either an unconfirmed gateway outcome (RequiresReview — the card MAY have been charged) or a gateway-accepted debit that hasn't settled yet (a Pending ACH with a TransactionId — money in flight). An unpaid Text2Pay link is NOT open; it holds nothing. Deliberately excluded from decimal InvoiceDto.AmountPaid so it never inflates a balance, but it still blocks void / revert / delete until the settlement sweep or a human resolves it.

hasSourceEstimateboolean nullable

Whether an estimate row points at this invoice (Estimates.InvoiceId == Id), i.e. the bill was converted from an estimate and revert-to-estimate has somewhere to go. False for a bill built directly in the Payments panel — revert would 409 NO_SOURCE_ESTIMATE, so the UI hides the control and leaves void as the exit. Null when the endpoint didn't compute it (only fulfillment-mapped responses do, e.g. GET /invoices/{id}); treat null as unknown, never as "no".

taxModestring

"us-sales-tax" or "vat" — snapshot at estimate creation.

notesstring nullable
mergedIntoInvoiceIdstring nullable

Set when this invoice was merged into a new combined invoice (it is then Superseded): the id of the successor bill.

mergedIntoInvoiceNumberstring nullable

Human-readable number of the successor combined invoice this one was merged into (set only on a Superseded source). Lets the UI link forward without a second fetch.

signatureDatastring nullable
signedAtstring date-time nullable
issuedAtstring date-time nullable

When the bill was issued (Draft → Unpaid) and its totals frozen. Null for Drafts and legacy invoices issued before the issue boundary.

isOnAccountboolean

House accounts (ITE-670): deliberately charged to the client's account.

dueDatestring date-time nullable

Due date (issue date + terms); set by charge-to-account, null otherwise.

createdAtstring date-time
updatedAtstring date-time
discountWarningsstring[] nullable

Set only on the convert-to-invoice response: estimate discount codes that could not be carried onto the bill (expired, usage limit, below minimum…), one message each. Null otherwise.

Changes

    • info

      added the optional property // to the response with the status (media type: text/plain)

    • info

      added the optional property // to the response with the status (media type: application/json)

    • info

      added the optional property // to the response with the status (media type: text/json)

    • info

      added the optional property /////// to the response with the status (media type: text/plain)

    • info

      added the optional property /////// to the response with the status (media type: application/json)

    • info

      added the optional property /////// to the response with the status (media type: text/json)

    • info

      added the optional property /////// to the response with the status (media type: text/plain)

    • info

      added the optional property /////// to the response with the status (media type: application/json)

    • info

      added the optional property /////// to the response with the status (media type: text/json)

    • info

      added the optional property // to the response with the status (media type: text/plain)

    • info

      added the optional property // to the response with the status (media type: application/json)

    • info

      added the optional property // to the response with the status (media type: text/json)

    • info

      added the optional property // to the response with the status (media type: text/plain)

    • info

      added the optional property // to the response with the status (media type: application/json)

    • info

      added the optional property // to the response with the status (media type: text/json)