After Andreas’ previous post about creating an invoice in Xero, I started to think about how ProcFu could be used to do the same thing in QuickBooks Online (QBO) as well. While it’s not a direct integration, using the oAuth API Services scripts, it’s a relatively easy process.
Before you do anything else, you need to add QBO as an API Service and authorize at least one user through it. You’ll need a Client ID and Client Secret, which you’ll get by creating an app in the Developer section of QBO. To start, you’ll only have access to the Sandbox environment; there is a deeper process to get a set of Production Keys in QBO, all the details of which are found on the Dashboard of your new QBO app.
You can check out Parts 1 and 2 of a previous series I wrote to help you handle the user authorization process, and you might also consider the ProcFu API Integrator App Pack to help you out. Regardless of whether or not you’re using the App Pack, you can find all the URLs you need for QBO integration in the APIs app of the ProcFu Users workspace.
Please take this as a huge disclaimer: I am not a QBO or accounting expert by any means, so to keep this simple, I’m only going to reference the parameters that are absolutely necessary. There are many options in the object attributes for “Create Invoice” for things like tax and discount, utilizing Products and Services with even more options, etc. so I invite you to visit the QBO API Documentation if you wish to discover all the options that are out there.
Step 1: Create Invoice
I have set up a very simple Invoicing system in Podio. It consists of two apps, an Invoices app and a Line Items app.
We’re going to use pretty much everything you see when interacting with QBO.
Let’s take a look at the flow that’s going to create the invoice.
PROCFU PROTIP: If you’ve been working with PF for a while, you may have experienced seemingly unexplainable 400 errors when sending requests. I’ve seen a lot of feedback from users on this situation, and in the majority of cases, it’s the result of using POST Params that have not been properly URL encoded. The easiest way to avoid this pitfall is to ensure that EVERY Param you use is a token, so you’ll see in my examples that I use variables for anything that’s not already found in the system. I highly suggest this process to avoid any unnecessary 400 errors.
Take a look at the “lines” variable. What we’re doing here is collecting all of our line items, sorting them by line number, and then using GlobiFlow’s function foo() to build an array. The function itself takes the existing array, converts it from JSON to PHP, adds a line item to the array, and then converts it back to JSON. Once the For Each is complete, you’ll be holding a JSON array of all your line items.
As previously mentioned, QBO has a very complex set of invoicing options, not all of which I have time or space to explain here, but just a note about “ItemRef”. This parameter refers to the “Products and Services” found in the Sales section of QBO. There is a notable limitation here as it’s difficult to ascertain what the ItemRef value is for each of your products and services (and QBO does not make it easy), but you can experiment with the API to GET each of your “Items” from the system and identify which is which. Items also have connections to Income and Expense accounts, and before I go crosseyed, I once again refer to my disclaimer. Just note that if you leave out “ItemRef” from your object (as it is optional), it will automatically select the Item with a value of 1, which in the Sandbox environment is a Service called “Services”. Because this is something that shows up on the final invoice, I wanted to make a special mention of it. Once you start exploring all aspects of the QBO API, you may consider creating your own integration to add and maintain your products/services in Podio and then return the Item IDs for future use.
Also, I'm just straight using the CustomerRef number of a dummy user in my Sandbox. In real life, you'd probably write a flow that creates and updates a Customer in QB, get the ID, store it in Podio and then use it when you need it, but if you understand this post, you can surely find your way through the API docs to do this.
I’m living dangerously by using Podio calculation fields to calculate my Line Item Total, which could potentially get you in trouble because in this flow, if UnitPrice * Quantity does not EXACTLY equal Amount, QBO will return an error. I leave it up to you to decide, but you could also use GlobiFlow to calculate these values prior to use in the call to QBO.
At the end of the flow, we capture the new Invoice Id for the second step of the process.
Step 2: Download Invoice
For those who may find it difficult to design a custom PDF of an invoice using either GlobiFlow or other external services, I have good news. QBO has a built in templating system that allows you to design your perfect invoice using easily customizable options. Even better news is that QBO has an API call that will let you download the invoice PDF. And the best news of all, there’s a new ProcFu script that takes the raw binary PDF data that QBO sends (in base64 format) and save it to a Podio item.
After both of these flows, you have a matching invoice in both Podio and QBO and you have a formatted PDF automatically provided by QBO that you can then immediately send to the customer.