Tips and FAQ

QuickBooks Online: Production OAuth Key

In QuickBooks, there is a difference between developer keys and production keys. If you create an Oauth2 connected app, chances are that app has developer keys. These keys will not allow you to connect to other QuickBooks companies. Reference this documentation for getting production ready keys: Production Keys

QuickBooks Online: How frequently does Quickbooks require an Oauth Refresh?

QuickBooks Online requires a token refresh every 180 days. The refresh cannot occur any sooner than 150 days. We handle the oauth refresh for you in the background by maintaining the last refresh date and determining if a refresh is necessary on each API call.

QuickBooks Online: Can I use the element for QuickBooks versions other than the United States version?

Yes. Currently QuickBooks Online supports development of apps in Australia, Canada, India, United Kingdom, and United States.

QuickBooks Online: Can I search for an invoice or bill by a customer's name?

No, QuickBooks allows users to search for customers by ‘customerRef.value’. This means that you would have to first make a GET/customers and search by the name. Then you can make your API call for what you are searching for.

QuickBooks Online: Does GET /purchase-orders Support Query By Purchase Order?

No, querying by pOStatus is not a supported feature of the QuickBooks Online API. You can perform a full selection from PurchaseOrder and then loop through the result set to pull out the open order details needed. A custom transformation or formula filter is recommended because the QBO PurchaseOrder API does not support using the postatus='OPEN' within the where clause.

QuickBooks Online: Why am I seeing "Authentication with the provider failed"?

If you are seeing the below error response when attempting to perform a QuickBooks Online call:

{ "requestId": "xxxxxxxxxxx",
"message": "Authentication with the provider failed. OAuth token refresh may have encountered problems. If problem continues, edit your element instance and ensure that access has not been revoked from the provider.",
"providerMessage": "3200 - message=ApplicationAuthenticationFailed; errorCode=003200; statusCode=401 – null” }

You can test a shorter refresh interval by using Intuit's Developer Playground using the below steps:

  1. Go to https://appcenter.intuit.com/Playground/OAuth/IA. Populate the key and secret and then specify how much time (in seconds) you would like to test for the expiration of your tokens.
  2. Click "Connect to Quickbooks". Go through the Oauth flow.
  3. After you have completed the Oauth flow, there will be a page that includes a realm id, token and secret. You will use these to POST https://api.cloud-elements.com/elements/api-v2/instances. You will use the following payload:
    {
    "element": {
    "key": "quickbooks"
    },
    "configuration": {
    "oauth.callback.url":"http://www.cloud-elements.com",
    "oauth.user.refresh_interval": "<time set in playground>",
    "quickbooks.realm.id" : "<realm id>",
    "oauth.user.token":"<token>",
    "oauth.user.token.secret":"<secret>",
    "oauth.api.key": "xxxxxxxxxxxxxxxxxxx",
    "oauth.api.secret": "xxxxxxxxxxxxxxxx",
    "quickbooks.datasource": "QBO",
    "oauth.user.refresh_time": "<current time converted to epoch, use http://www.epochconverter.com/>"
    },
    "tags": [
    "QBO Token"
    ],
    "name": "QBO Token",
    "externalAuthentication": "initial"
    }
  4. After you have posted the instance, continually call one of the endpoints from the instance until the refresh interval has expired. For example, if you set it to 120 seconds, make sure you are making API calls for at least two minutes.
  5. Immediately after the refresh interval has passed, do another call to ensure it is still working.
  6. Do a GET /instances/{id}. Review the oauth.user.refresh_time and see it has been updated to when the token was refreshed.

NOTE: due to the shorter time interval, you run the risk of getting a "Refresh out of bounds" error message if you don't attempt it within a specified time frame. This is a QuickBooks limitation.

QuickBooks Online: How can I get my application approved for the QuickBooks App Store?

There are currently no known blockers to getting approved on the QuickBooks App Store when utilizing Cloud Elements. A few of our users have been successful in getting their app approved for the QuickBooks App Store. More information on the approval process can be found on the QuickBooks Developer Documentation.

QuickBooks Online: Why do I get "INTERNAL_SERVER_ERROR" when syncing customer invoices?

The below error might be seen when trying to sync customer invoices:

java.lang.RuntimeException: {"message":"getCustomerById failure","endpoint":"https://console.cloud-elements.com/elements/api-v2/hubs/finance/customers/1042","headers":{"Content-Type":["application/json"],"Authorization":["Elementxxxxxxxxxxxxxxxxx=, User=xxxxxxxxxxxxxxx"]},"responseStatusCode":"INTERNAL_SERVER_ERROR","responseBody":"{\"requestId\":\"xxxxxxxxxxxxxx\",\"message\":\"Unknown internal error\"}"}

QuickBooks Online only allows one connection per user ID. If you create one instance, and a second instance with the same user ID, then the second instance will revoke access to the first one.

QuickBooks online has a sync token attached to each ID. When you perform a GET /invoices call, the ID will appear as: 1234|3. This translates to <id>|<sync token>

The sync token helps manage concurrent requests. Only the request with the most recent sync token will succeed. When you PATCH /invoices, send the ID with the most recent sync token.

QuickBooks Online: Why do I see "This app is not set up to allow connection from your country" when creating an instance?

This error is seen when you attempt to create an instance from a country that is not enabled on the QuickBooks Online app. QuickBooks Online allows you to choose several countries for each app. Add the country where you are attempting to connect from as explained in QuickBooks Online Documentation.

Quickbooks Online: Uploading Invoice Attachments

Uploading attachments to specific objects in Quickbooks Online (QBO) including Invoices and Bills is a straight-forward process, but if you are using the element API Docs to upload these attachments there is one important note to make. The /attachments endpoints for these objects are available towards the bottom of the API docs within this resource:

/{objectName}/{id}/attachments

The reason for this is to keep the API docs more in line with how QBO actually handles the upload of attachments to objects as a separate API and not as a function of the Transaction Resource APIs themselves. For example you can make POST calls with the uploaded files to these endpoints:

/invoices/{id}/attachments
/bills/{id}/attachments