{
  "TxnID": "4E4-1703631996",
  "TimeCreated": "2023-12-26T15:06:36-08:00",
  "TimeModified": "2023-12-26T15:06:36-08:00",
  "EditSequence": 1703631996,
  "TxnNumber": 35,
  "CustomerRef": {
    "ListID": "80000020-1703631977",
    "FullName": "Test Customer"
  },
  "ARAccountRef": {
    "ListID": "80000024-1693948049",
    "FullName": "Accounts Receivable"
  },
  "TemplateRef": {
    "ListID": "80000003-1692738438",
    "FullName": "Intuit Service Invoice"
  },
  "TxnDate": "2021-09-01",
  "RefNumber": 12,
  "IsPending": false,
  "IsFinanceCharge": false,
  "DueDate": "2021-09-01",
  "ShipDate": "2021-09-01",
  "Subtotal": 100,
  "SalesTaxPercentage": 0,
  "SalesTaxTotal": 0,
  "AppliedAmount": 0,
  "BalanceRemaining": 100,
  "IsPaid": false,
  "IsToBePrinted": true,
  "IsToBeEmailed": false,
  "InvoiceLineRet": {
    "TxnLineID": "4E6-1703631996",
    "ItemRef": {
      "ListID": "80000036-1703631990",
      "FullName": "Construction Work"
    },
    "Rate": 100,
    "Amount": 100,
    "SalesTaxCodeRef": {
      "ListID": "80000002-1692738438",
      "FullName": "Non"
    }
  }
}

An invoice in QuickBooks Desktop records the amount owed by a customer who purchased goods or services but did not pay in full at the time of the sale. If full payment is received at the time of the sale, it is recorded as a sales receipt, not an invoice.

To see all of the request parameters and response fields for , check out our client library’s amazing autocomplete.

Fetching invoices

Each invoice in QuickBooks Desktop has several line items, which you would typically want to include when fetching invoices. The following example does just that:

Fetching all invoices with line items
const invoices = await conductor.qbd.invoice.query("{{END_USER_ID}}", {
  IncludeLineItems: true,
});

Invoices are also assigned to specific jobs under a customer or to the customer directly when not related to a particular job. The following example fetches all invoices for a specific customer:

Fetching all invoices for a specific customer
const invoices = await conductor.qbd.invoice.query("{{END_USER_ID}}", {
  EntityFilter: {
    FullName: "Test customer 1234",
  },
  IncludeLineItems: true,
});

Here is an example of fetching invoices modified (or created) after a specific date:

Fetching invoices modified after a specific date
const invoices = await conductor.qbd.invoice.query("{{END_USER_ID}}", {
  ModifiedDateRangeFilter: {
    FromModifiedDate: "2024-04-01",
  },
  IncludeLineItems: true,
});

Creating invoices

An invoice is a complex object with many associated objects. To create an invoice from scratch, you either need the identifiers (e.g., ListID) of the required associated objects, or you must create the associated objects first.

The following example uses mock data to create an invoice in QuickBooks Desktop, which also requires creating a mock customer, account, and service-item using the add() method of each object. The add() method returns the created object, which contains the ListID identifier to associate the objects with each other.

Creating an invoice
const END_USER_ID = "{{END_USER_ID}}";
// Use unique names for mock objects because QBD requires each to be unique.
const UNIQUE_SUFFIX = Math.random().toFixed(6);

const customer = await conductor.qbd.customer.add(END_USER_ID, {
  Name: `Test customer ${UNIQUE_SUFFIX}`,
});

// An invoice cannot be empty, so we must create an item to add to the invoice,
// and every item requires an account, which we must create first.
const account = await conductor.qbd.account.add(END_USER_ID, {
  Name: `Test income account ${UNIQUE_SUFFIX}`,
  AccountType: "Income",
});

// Create a service-item for the invoice with the account we just created.
const serviceItem = await conductor.qbd.itemService.add(END_USER_ID, {
  Name: `Construction work ${UNIQUE_SUFFIX}`,
  SalesOrPurchase: {
    Price: "100.00",
    AccountRef: {
      ListID: account.ListID,
    },
  },
});

const invoice = await conductor.qbd.invoice.add(END_USER_ID, {
  CustomerRef: {
    ListID: customer.ListID,
  },
  TxnDate: "2021-09-01",
  InvoiceLineAdd: [
    {
      Amount: "100.00",
      ItemRef: {
        ListID: serviceItem.ListID,
      },
    },
  ],
});

Updating invoices and line-items

To modify existing line-items or add line-items to an invoice, QuickBooks Desktop requires that you include all unmodified line-items in the update request, even the ones you do not want to change. Otherwise, QuickBooks Desktop will remove the line-items you did not include in the update request. Hence, we recommend you first query the invoice you want to update, then update that invoice with the new line-items you want to add or modify while including all the existing line-items returned from the query.

Updating an invoice by adding a new line-item
const END_USER_ID = "{{END_USER_ID}}";

const newInvoice = await conductor.qbd.invoice.add(END_USER_ID, {
  CustomerRef: {
    FullName: "Test Customer",
  },
  Memo: "New invoice",
  InvoiceLineAdd: [
    {
      ItemRef: {
        FullName: "Test Item",
      },
      Desc: "First line item",
      Amount: "100.00",
    },
    {
      ItemRef: {
        FullName: "Test Item",
      },
      Desc: "Second line item",
      Amount: "200.00",
    },
  ],
});

const updatedInvoice = await conductor.qbd.invoice.mod(END_USER_ID, {
  TxnID: newInvoice.TxnID,
  // `EditSequence` from the original object is required to update
  // any QuickBooks Desktop object.
  EditSequence: newInvoice.EditSequence,
  Memo: "Updated invoice",
  InvoiceLineMod: [
    // QuickBooks Desktop requires that you re-include the
    // existing line items in the request. Otherwise, it will
    // remove them from the invoice.
    ...newInvoice.InvoiceLineRet,
    {
      ItemRef: {
        ListID: inventoryItems[0].ListID,
      },
      Desc: "Item 3",
      // Set `TxnLineID` to -1 to add a new line item.
      TxnLineID: "-1",
    },
  ],
});