A Sales and Marketing Director's Guide To Getting Data From Jira Into Quickbooks Online

Choose a coding platform

The first thing your developer will do to set up your tool is to choose a coding platform. You want a platform that has wide adoption so that there will be plenty of useful packages to choose from. This saves you time and effort. The other thing that matters quite a bit with your platform choice is reliability and flexibility. Can applications built on the platform perform well under load? Are they easy to maintain and adapt over time?

Some examples of excellent platforms are Laravel in the PHP world and Next.js in the Javascript world.

Assemble smart packages

Now that you have your coding platform your developer can go shopping for software packages. In this case we're going to connect to the Quickbooks Online API as well as the Atlassian API. These are widely used products and there are plenty of open source ready-made packages available that do most of the work for you.

Check out this example of a Laravel PHP package to connect with QB Online. I have been using this one myself and am finding that it saves me tons of coding time.

Make it secure

The API's you're connecting to require authentication. You can't just interact with them without permission. They both use the industry standard OAuth 2 protocol. Here's how OAuth 2 works:

OAuth expects all interactions between 2 systems to take place as a specific user in each system. Someone has to login and establish the connection. So OAuth begins with a login event.

  • One of your users will click a link on your tool to login.
  • Next they will bounce to the OAuth server of the API provider, for example Atlassian.
  • Atlassian will have them login with their Atlassian user account.
  • Then Atlassian will ask them to grant permissions for your application to use the Atlassian API on your behalf.
  • Once permission is granted, Atlassian will bounce the user back to your server to a specific url that includes a special code in it.
  • Your server will receive this code and make a call behind the scenes back to Atlassian. (You want to verify that the code was actually created by Atlassian as part of your initial login attempt to keep both systems secure).
  • Behind the scenes Atlassian confirms that the code is valid. It returns to your server a special access token that your code can use going forward to securely make valid API calls.
  • Once this access token expires your code needs to request a fresh one or it needs to run the user through the OAuth authentication flow again.

Host it somewhere

Since the OAuth connections need to be able to call back to your application your web developer will need to run things from an actual domain hosted on an actual server somewhere. This used to be harder than it is today. These days in about 5 minutes you can have an inexpensive PHP or Node server instance running on Digital Ocean with a new domain name pointed to it.

For example, the domain is available for $10 bucks a year on Namecheap right now. And hosting it for a month on Digital Ocean would only cost you $6 bucks. All of that could be up and running in 5 minutes.

Build some proofs-of-concept

This is the really fun and important, yet frustrating step. Your web developer should check all the connections and try to break stuff. When doing API integration work you want to bubble up to the surface all of the weird and difficult-to-solve problems early on. Developers do this through proofs of concept.

For example, all of our API integration work includes CRUD tests. These are tests in all the relevant systems that verify that we can write and run code that Creates, Reads, Updates and Deletes the kinds of records we care about. If your developer can achieve CRUD, they can likely do anything.

Here’s an example of a code snippet in Laravel that would add a time entry to Quickbooks Online. It assumes that you grabbed the data from Jira in a previous step. It also assumes that your developer has invoked some useful Laravel classes.


        $timeEntry  = [
            'NameOf'  => 'Employee',
            'TxnDate' =>  $time['started'],
            'Hours' => $time['timeSpentSeconds'] / 3600,
            'HourlyRate' => '85.00',
            'BillableStatus' => 'NotBillable',
            'EmployeeRef' => [
                'Name' => 'Emily Platt',
                'Value' => '55'
        $t  = TimeActivity::create($timeEntry);
        $response   = $quickbooks->getDataService()->Add($t);


Authenticate against the Quickbooks Online API

You have made it through the proof-of-concept work. You have uncovered and worked through weird outlier issues. Now you're ready to build the skeleton of the system. Users need to log in to both Quickbooks and Atlassian to do anything. We'll take Quickbooks first.

With OAuth 2 based systems your developer needs to create an 'application' inside Quickbooks Online. That application is how the owner of the Quickbooks instance gives permission to an outside system to gain access to data. The application inside QB will provide an OAuth 2 client id and client secret. These are used by the requesting system to ask to allow a user to start the authentication flow.

Once the application is in place inside QBO a developer can complete the set-up of the full login flow. This will allow users to login and have an API token associated with their account behind the scenes. Subsequent scripts will then use this token to make API calls and do work in your new system.

Here’s a code snippet that serves as an example of getting an authorization token from the Quickbooks Online API. (This is from the Laravel Quickbooks package mentioned above):


    $oauth_token = $this->getDataService()
                        ->exchangeAuthorizationCodeForToken($code, $realm_id);



    return $this;


Authenticate against the Atlassian API for Jira

The same thing the developer did in Quickbooks Online will be done in Atlassian. Set up an 'application' in order to grant permissions for OAuth calls to be made. Grab the client id and client secret. Get your developer to build up the authentication flow. And Robert is your father's brother!

Here’s what the application looks like inside Jira:

QBO Laravel accounting screenshot

And here’s a little example snippet of how to get the authorization token from Atlassian using Laravel Socialite:


$user = Socialite::driver('atlassian')->user();

Session::put('jira-access-token', $user->token);

return redirect('/home');


Create some dedicated scripts to retrieve records from Jira to send into Quickbooks

Ok, now work happens. You have proven your concepts by running CRUD scripts. You have authentication working with QBO and Atlassian. Now your developer can start writing cool little utility scripts to grab data from one place and pass it over to another.

When you have software in the middle of the API data flows you gain the opportunity of refining the data as it moves. This is very useful and usually remains a valuable place to build and manage important business logic over time.

But before a developer succumbs to the idea that their code has to do everything automagically, know that in some cases it can be even more handy to have tables of data brought in from one system, plopped into a form where a human can review it and alter it here and there, and then send it on through to the other system.

For example, imagine you’re tracking time for projects in Jira. Before some work items land in Quickbooks you might want to alter the descriptions. Your developer can build a tool to allow you to do this easily. This approach can lower the requirement that your developer's code accounts for all sorts of data outlier cases.

Here’s an example code snippet of grabbing all of the worklogs for a given issue in a project in Jira. Your developer would loop through these worklogs and save them to Quickbooks Online as time activity entries:


    $endpoint       = '' . $jiraCloudId . '/rest/api/3';
    $worklogs       = Http::withToken($token)->get($endpoint . '/issue/LEAD-432/worklog');
    // Do something clever with the worklogs…
    print_r($worklogs->json()); exit();



You now have the outline of a pretty useful integration utility. Tools like this are the sorts of things that we build for clients for their corporate intranets. Since this is an accounting related guide, the accounting business units might be your best friend if you built out something like this and handed it off to them.

We should all remember to be on good terms with our accountants.