QuickBooks Integration - Follow Along as I Struggle [So You Don't Have To]

Okay, I’ve got an update… I’m not sure if my use case is similar enough to be helpful for you guys, but happy to share in case it is. I’m not trying to use Quickbooks as an identify provider for login, I just want customers who have already signed up with my app to connect their Quickbooks account so I can aggregate some data for them (potentially asynchronously on a schedule).

Because of that I built the Oauth flow without using bubble’s native support. Here are the steps I went through, happy to provide more details if it’s helpful.

BTW this video was really helpful for me… I’ve been around OAuth but not in it, and this helped me feel much less dumb about it https://www.youtube.com/watch?v=996OiexHze0

Okay here goes:

  1. Set up my account with Intuit like they tell you to here
  2. Set up a new data type in bubble that I called OAuth Connections:
    image
  3. Create/choose a page for people to connect from (with a “Connect Quickbooks” button from their styleguide, as well as a callback page for them to come back to. For me I choose QBO-Link and QBO-Landing respectively
  4. I went through the steps Quickbooks recommends in their playground, and added my bubble /QBO-Landing as a redirect URI. I also got the authorization code from the playground for my own sandbox so I could initialize the API in Bubble (do a real call so they can map the return fields):
  5. Okay so this is the fun part… on the QBO-Link page I have a workflow item to ‘Open an external website’ when someone clicks on the Connect to QBO button. The critical thing with this is the format, which I just copied from the playground URL. As with any OAuth authorization request, you just need your client ID (which you get from the “Keys & OAuth” page under “My Apps” in the intuit dev portal), a space separated (but encoded) list of the scopes you want, and the redirect_uri you want people to be sent back to after authing. I just selected the scopes I wanted in the playground and copied the URL:
    https://appcenter.intuit.com/app/connect/oauth2?client_id=[your_client_id]&scope=com.intuit.quickbooks.accounting%20openid%20profile%20email%20phone%20address&redirect_uri=[Your_Redirect_URI]&response_type=code&state=PlaygroundAuth#/RealmSelection
    Now when so when someone clicks on that link, they’ll be sent to Quickbooks to authorize the request, and then sent back to the redirect_uri I provided.

Quick note… best practice here from what I can tell is to generate an additional token on your side (calculate formula, generate a random string) and append that to the state parameter. When the redirect comes back you’ll want to use an “only when” to make sure no one’s spoofing these requests… I haven’t taken the time to do that yet, but should be straightforward.

  1. Okay now we need to get ready to catch the auth code and realm ID that will be parameters on the URL quickbooks sends the customer back with, so I need to set up the token exchange API. I messed with this for a long time… essentially QBO’s documentation is both inconsistent, and fully inaccurate. They tell you to base64 encode your client ID and key separated with a colon and use that as auth, but that never worked for me and others seem to be seeing the same thing. The other complication is that bubble’s api connector doesn’t appear to have native support for content-type x-www-form-urlencoded values, so you have to jimmy it a bit.
    Follow everything that’s in the screenshot, and the Content-Type value in the header that’s cut off is application/x-www-form-urlencoded
    In the body you’ll want to drop in your client id and secret:
    code=<code>&redirect_uri=<redirect_uri>&grant_type=authorization_code&client_id=[your client ID]&client_secret=[your secret]

  2. Once that’s set up you need to initialize it. This took me a while to figure out, just make sure that you’ve pasted in values from the playground so the call will actually work. Also remember that the auth code can only be exchanged once, so you’ll need to reauthorize (first step) in the playground if you’ve already done the exchange with the auth code. I think I also had to check the capture response headers checkbox for initialization to actually work.

  3. Now we’re ready to actually auth someone… on the landing page I’ve got a few different events… essentially I want to take the auth code I get from quickbooks in the URL and exchange it for an access token and refresh token that will allow me to make API calls on their behalf. In both the create/update workflow steps you’ll use the API endpoint we just created, which I called Initial auth code exchange. For the code you’ll grab that from a page parameter, make sure to save the refresh token, and same with the realm ID which you don’t need for this call but you’ll want to persist anyway. I’m planning to add more data sources which is why I have the API field in my data type, where I’ve marked this as a QBO connection.



image

  1. Refresh token - The Access token that you receive is only good for an hour, so you’ll need the ability to refresh it by making an API call with the refresh token and your key and secret (hence why it’s so important to save the refresh token in the previous step). I have a simple backend workflow that just takes the OAuth entry, and I plan to call that whenever I get an API error where a token is expired (haven’t set that up yet, but may just have to assume this is what’s up if data doesn’t come back). Here’s the backend workflow, I’d just schedule it from the app when necessary with a scheduled date of current date/time.
    The reason I’ve got the refresh token updating is because of the note at the bottom of the page here. Apparently it changes all the time, so you’ll want to save the latest one that comes back when you refresh.



    image

  2. From that point forward I’ve got access tokens and can hit any API for QBO.

Hope that helps!

5 Likes

Wow this is amazing! Let me give this a shot and I will let you know! Thank you so much

@zenter I have gotten to step 6 (farthest I have gotten thus far) so great job. I am getting an error at step 6 however. This is what the error reads. I think it may be the redirect uri. What did you put in for that in step 6?

@zenter I figured it out! It was because I had copied and pasted application/x-www-form-urlencodedIn from your post when it should be application/x-www-form-urlencoded of course! Took a second to catch though!

lol sorry about that, fat fingered the “In” there. Fixed now.

Glad it’s working for you!

1 Like

@zenter’s walkthrough above works like a charm! You will be able to call any QBO call with it. Been using it for a few days now.

Great work and thank you so much for sharing @zenter

2 Likes

Great to hear! Navigating some of the QBO reports has been a bit of a doozy for me… finding that simply getting a customer’s total inventory or total accounts receivable isn’t super straightforward.

Have you bumped into anything like that? Inventory can be three nested rows in in the balance sheet report, or four… AR can be in a group called “AR” where it’s easy to grab, or custom named with no reliable grouping. Each can be in their own reports (Inventory Summary or AR Aging) but not necessarily… so in some cases I’m looking in three places and taking the max value, but I figure there has to be a better way. Likely a question for the QBO forums rather than here I guess.

1 Like

Hi guys,

@brad.h @schnetzlerjoe @zenter @blake1

We have pushed an update with new version of our plugin. Everything should be up-and-running. Please do upgrade it to the latest version, refresh your app and give it a try again.

Also, please check the following updated resources, for guidance:

Thank you for patience and apologies for inconveniences.

Best regards,
Zeroqode Team

I’m new to Bubble and have been trying to follow along with this thread. So far, I’ve been able to get past the user login stage. However, I am trying to hit some of the API endpoints and I am totally lost on how to do that. For instance, I want to run a P&L report. What “module” or “action” do I need to utilize in Bubble to make that happen?

Many thanks in advance!

Amazing work! Been able to follow through all the steps.

I did have one issue however. I’ve been able to authorize using OAuth2 and receive an auth code, but after I get redirected my workflow to be able to exchange that auth token for an access token and refresh token doesn’t work. It says I have an invalid grant token even though the access token and realmId comes back in the URL.

Any thoughts?

I got it to work with the API Connector in a much simpler way. Mine is currently working and I’m so excited I wanted to share with the world. Could someone test this?

So, on and off over the past few months, I’ve many early mornings on this. Directly on Bubble, using both of Zeroqode’s plugins, reading forums all over the place. The answer to my problem was QB’s inconsistency in phrasing.

tl;dr: use the scope com.intuit.quickbooks.accounting openid profile email phone address. No capitals, no commas.

Here’s my setup:

Here’s the pop-up confirmation.

I’m still testing to see if the token remains valid for backend workflows and, if after the refresh token expires - in 101 days - what kind of errors will it give.

1 Like

@rico.trevisan this looks beautiful. I don’t want to rely on a plug-in. It’s the first I’ve seen the direct API setup. Thank you.

I’ll experiment with this soon. Keep us all posted as the token expires. Thanks again!

Hmmm… the token is not sticking.

I’m not able to reproduce the precise steps, but it seems to be due to a bit of time and refreshing the editor.

Is it a bug in the API Connector?

1 Like

Anyone who is still looking for Quickbooks integration. What kind of use cases are you interested in? I’m about to record a tutorial series integrating Bubble with Quickbooks and could do with some inspiration for the tutorial example!

Thanks in advance, feel free to reach out privately if you’d prefer!

@dantidmas88 that would be interesting to see. If you could set up the API connector and token situation, that would be a great start. As an example you could be a landscaping or cleaning company that uses a quickbooks for accounting and a bubble app for proposals. After the API and tokens are set, it would be nice to see customer lists auto imported from QB and then show in the bubble app. Then a proposal created in the bubble app to auto generate a proposal in QB.

Interesting, thanks. Here’s our use case. Customers pay us via Iugu, our payment gateway. Every time they pay us, I want to register that in QB:

  1. customer (if doesn’t exist already)
  2. invoice (enriched with some customer information “QB.class”)
  3. transaction

That way we can do the reconciliation with the bank account.

@brad.h @rico.trevisan @dantidmas88 - has anyone managed to get this working yet using the bubble API connector? I’m getting the error message below. If you’re able to share your setup or any thoughts, it would be greatly appreciated.

Not yet. I’m still using Integromat.

I’ve tried the Zeroqode plugins - both of them. And it doesn’t work for server side. I’m going to give it a try again next week.

Here’s the reply from the Bubble team regarding my bug report:

Every API has a certain expiry on its tokens and sometimes they actually just require logging back in as a security measure instead of automatically refreshing. Looking at the Quickbooks API it appears that refresh tokens should be good for 100 days.

We cannot guarantee that Bubble will “play nicely” with every single API OAuth since they are all different; however, when this happens, a solution is to integrate manually with custom API calls that handle the token and refresh.

On a side note, I wonder if “requesting an access token uses basic Auth” is playing a role here. Most modern APIs don’t use basic Auth to exchange “code” for “access_token” and I am curious as to whether the app is successfully getting the original token using the normal Auth screen, then failing when it tries to exchange “refresh_token” for another “access_token” because basic Auth isn’t actually being used.

Since this is a custom integration, our team is unable to offer full support and the forum is the best way to find solutions with the help of users having made similar integration.

I do acknowledge that a Bubble made plugin for Quickbooks would be a great addition and I have submitted a feature request to our engineering team.

You should check out Pathfix, I know it comes with additional cost but it removes the oauth headache entirely. That is what I had planned to use for the tutorial just didnt get round to it. Super easy to setup though and handles Quickbooks already.

1 Like

@stu_bowes not yet. The token is still the issue.

@dantidmas88 thanks for suggesting Pathfix. It’s the first I’ve heard of it. I’m wondering if Pathfix would let users of my app oath to QB. I’ll explore this a bit. Thanks!