Invoice

Insert a payment for an invoice

Record a payment against an invoice. On success the invoice's paid_amount, remaining_amount, and payment status are recomputed to reflect the new payment.

The recorded amount is capped at the invoice's outstanding balance (its remaining_amount): only the portion up to that balance is applied to the invoice, and any excess becomes a customer credit for the account. In the response, the payment's amount holds the applied (capped) portion and the generated credit appears in overpayment_credits with the excess as its amount. On the invoice, paid_amount grows by the applied portion only, so it ends equal to total, remaining_amount drops to 0, and status becomes FULLY_PAID — an overpayment never produces OVER_PAID. For example, sending an amount of 150 against an invoice with a remaining_amount of "100.00" returns a payment with amount "100" and one entry in overpayment_credits with amount "50"; the invoice then reads paid_amount equal to total, remaining_amount "0.00", and status FULLY_PAID. A payment cannot be filed against an invoice that is already fully paid, or against a voided invoice — both are rejected. Returns 404 when the invoice does not exist in the caller's company, and 403 when the API key's user cannot see it under their team restrictions.

If the company is connected to QuickBooks Online there are two extra behaviors. First, Distru synchronously pulls the latest payment and credit data from QuickBooks Online before recording, which can briefly fail with a "try again in a few seconds" error while that refresh runs — retry the request in that case. Second, the payment (or its invoice) is only queued for sync to QuickBooks Online once its dependencies are already synced there; otherwise the sync is deferred. A 200 is therefore not confirmation the payment reached QuickBooks Online — the response's quickbooks_sync_enqueued flag tells you whether a sync was queued, and you should poll QuickBooks Online to observe the final result. The payment may also be pushed to LeafLink when that integration is configured for the customer.

Required permission: invoices_permissions_receive_payment. The authenticated user must also be allowed to view invoices under their team restrictions.

post/public/v1/invoices/{id}/payments

Request

  • Base URL
    https://app.distru.com
  • Auth
    HTTP bearer

Path parameters

idstring required

The id of the invoice to record the payment against — the id returned by the list and show invoice endpoints.

Request body

payment_method_idstring required

The id of the payment method to record this payment under. Required. Retrieve valid IDs from GET /public/v1/payment-methods.

amountnumber required

The payment amount. Required. Rounded to 2 decimal places. Capped at the invoice's remaining_amount: only the portion up to the outstanding balance is applied — that portion is returned as the payment's amount and added to the invoice's paid_amount — while any excess becomes a customer credit, returned in the payment's overpayment_credits. E.g. sending 150 when "100.00" remains records a payment of "100" and a credit of "50".

payment_datetimestring required

The datetime the payment was made, as an ISO8601 datetime (e.g. 2026-08-20T00:00:00Z). Required.

descriptionstring required

A free-text description of the payment. Required.

quickbooks_deposit_account_idstring

QuickBooks Online deposit account ID. Optional. Mutually exclusive with quickbooks_deposit_account_name — sending both is rejected. When your company is connected to QuickBooks Online and you send neither, the payment is deposited to the company's Sales Deposit Account (Settings → QuickBooks); when that account is missing, not active or not of an allowed type, the request is rejected with a base error naming it — send an account then. With no Sales Deposit Account set, sending neither is rejected on both deposit account fields. When your company is not connected to QuickBooks Online, sending this is rejected. The account must be active and of type "Bank" or "Other Current Asset".

quickbooks_deposit_account_namestring

QuickBooks Online deposit account name. Optional. Mutually exclusive with quickbooks_deposit_account_id — sending both is rejected. Omit both to use the company's Sales Deposit Account (see quickbooks_deposit_account_id). A name containing : is a sub-account's full name (Parent:Child) and matches that account exactly; it must itself be active and of type "Bank" or "Other Current Asset". Any other name matches among active "Bank" and "Other Current Asset" accounts: a top-level account with that name (its full name) wins; otherwise the one sub-account with that short name. A short name shared by several such sub-accounts is rejected with a message listing their full names — send the full name instead. When the top-level account with that name is inactive or of another type and a sub-account shares its name, the request is rejected with a message naming that sub-account's full name, rather than depositing to it. When your company is not connected to QuickBooks Online, sending this is rejected.

Response

A single payment

Example response

{
  "data": {
    "company": {
      "id": "3f128a34-cc59-4b49-8883-23bf10e59c6c",
      "name": "Retailer 1"
    }
  }
}

Changes

No recorded changes to this operation across all 17 revisions of this API.