So You Want to Integrate with QuickBooks Desktop...

Don't do it!

You'll spend $60,000 - $100,000 of development time in the first year, and triple your support costs.

If you're being held at gunpoint, though, a few key insights can save you years of development and support headaches. Let's start with the basics.

A system overview

For your app to talk to QuickBooks Desktop, your user will need to install Intuit's QuickBooks Web Connector alongside QuickBooks Desktop for Windows. The web connector is a SOAP client that will expect your app to have a SOAP server it can communicate with.

Once configured, it will poll your SOAP server at a specified interval.

QuickBooksQuickBooksQB Web  ConnectorQB Web  ConnectorYour customer's Windows 95 computerYour customer's Windows 95 computerQuickBooks  SOAP serverQuickBooks  SOAP serverThe rest  of the appThe rest  of the appYour appYour appSOAP/QBXMLSOAP/QBXML

If your app is written in Java, congratulations! There are plenty of SOAP server implementations lying around. For the rest of us, a graveyard of abandoned OSS projects await...

Establishing the connection

For the web connector to authenticate against your app, your user will need two things from you:

  1. a QWC file 🚧 that specifies your app's QuickBooks endpoint url, a username it will use to log in, and some other metadata. Prefer generating a username that is account-wide rather than user-specific.
  2. a password - again, prefer generating an account-wide password rather than using a user's existing password.

Once the user has installed the QWC file you generated into their web connector and entered their password, they can now connect to your app.

The ideal exchange
serverVersionserverVersioncloseConnectioncloseConnectionclientVersionclientVersionauthenticateauthenticatesendRequestXMLsendRequestXMLreceiveResponseXMLreceiveResponseXMLuse the current company fileuse the current company filepercentage completepercentage completethe QBXML request for Quickbooks to answerthe QBXML request for Quickbooks to answerQB Web  ConnectorQB Web  ConnectorQuickBooks  SOAP serverQuickBooks  SOAP server% complete < 100% complete < 100

The protocol for exchanging data

To build your SOAP server, you'll need to implement the short list of functions expected by the web connector. These should all be available under a single endpoint that accepts and returns XML in the SOAP/QBXML format.

You'll also want to save your app's requests for QuickBooks in a queue, and manage the iteration over batched queries (any time you might receive more than 10-15 records in response).

Simulate Creating an Invoice

Modeling the data

When planning your integration architecture, know that many therapy sessions can be avoided if you keep QuickBooks as the source of truth. Two-way syncing has many dragons that _can_ be slain, but you need a great justification for it ($$).

Starting out, it's tempting to reduce data duplication and insert the data you get from QuickBooks directly into your domain models. This might be OK for some use cases, but ask yourself a few questions:

Could multiple sources feed conflicting information into the same model? For example, you might have the notion of "Contacts" in your app. Perhaps they can be connected to both a HubSpot record and a QuickBooks record that shouldn't necessarily be forced to stay in sync.

It also means rather than overwriting data when importing a contact, you're simply creating a relationship that can be displayed in the UI, undone, changed, or removed.

QuickbooksCustomersQuickbooksCustomersjoin tablejoin tableContactsContacts
Using a join table instead of merging everything together prevents many headaches.

Keeping your QuickBooks data isolated, and modeling your QuickBooks domain to match QuickBooks' own internal structure (or at least the portion you're interested in) will give you needed degrees of freedom and reduce heartache.

You're finally ready to start importing data

Most integrations are primarily concerned with customers, items, and invoices. If you want to manage journal entries you'll need the chart of accounts, and managing purchase orders requires vendor information.

Simulate a Customer Import

Upserting into QuickBooks

QuickBooks doesn't have an `upsert` function, so we need to be smart about inserting and modifying records. This includes querying for a customer before attempting to create one, and deduplicating add/modify requests generated by your users. Use the simulation to see how we can safely add new records and ensure updates are applied correctly using QuickBooks' "edit sequence".

Simulate Adding a Customer

When things go wrong...

The many faces of QuickBooks errors

No matter how thorough you are, there will be errors. Some will be your fault; some will be because the Azerbaijani version of QuickBooks processes tax completely differently; some will be because your users are...users.

The best thing you can do for yourself is to implement unreasonably verbose logging throughout your integration code, and record both the QBXML you're sending to QuickBooks as well as any errors returned. Keep an errors table referencing the request, the error code, and error message to expedite discovery and solutions for the inevitable hair-pulling moments when you're questioning your life choices.

And most of all

Make sure everyone in your organization knows this is a long-term commitment. You will not ship this and return to cranking out feature requests; you are the proud new parent of a very needy child. You will be discovering edge cases, fixing bugs, and jumping into many new and exciting support conversations for a long time to come. Expect overall development speed within the organization to slow until things stabilize.