Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a simple way to access the Quickbooks API using OAuth2?

I just need to access data in my Quickbooks Online (QBO) company using an API with C#. But now they've moved to OAuth2 it looks very complex. For example, it suggests I need a redirect URI to receive the authorization code but I'm writing a simple console app to export data to QBO and don't want to have to host a URI endpoint to do that.

It's also confusing to know how to get and manage the following:

  • Client ID
  • Client Secret
  • RealmID
  • Authorization Code
  • Refresh Token
  • Access Token

There must be a simple way of doing this. For example, with Stripe you only have to manage an API key.

like image 801
mpipe3 Avatar asked Jan 26 '19 17:01

mpipe3


1 Answers

After some research I found this can be done in a simple way. You only need to keep a copy of the refresh token (perhaps in a read/write file). When you want to access the API just call OAuth2Client.RefreshTokenAsync() to get an access token. All the other items required can be found using the OAuth2 playground.

The access token can then be used for up to one hour with the API. You may also get back an updated refresh token. If that happens just store that for future use. The refresh token lasts up to 100 days before you must use a newer version that was returned from the Refresh Token operation.

Here's a longer version of how to use the API from C#:

  1. Create an app but don't publish it in the QBO app store. To do this login to developer.intuit.com using your QBO account. Go to 'My Apps' Then create an app (e.g. called 'MyQBOApiApp'). This only needs to be done once. Leave the default redirect URL set to the OAuth2 playground as this is the only redirect URL required.

  2. Get the Production Client ID and Client Secret from the 'Production Keys' section of the 'OAuth 2.0 Keys' tab for the app. (Record these for use in your C# program as they don't change)

  3. Goto the OAuth 2.0 playground at https://developer.intuit.com/app/developer/playground

  4. In step 1 'Get Authorization Code' select MyQBOApiApp(Production) from the drop box list

  5. In the Select Scopes list select 'Accounting' if you just need to read/write data to your QBO company

  6. Click on 'Get authorization code'

  7. Connect your QBO company to the MyQBOApiApp app

  8. In Step 2 'Get OAuth 2.0 token from auth code' on the playground page click 'Get tokens'. This will get a refresh token for your API access to your company.

  9. Skip to Step 4 'Refresh access token' on the playground page. The Access Token is only usable for 59 mins so just keep the 'Refresh Token' as it can be used for 100 days to get new access tokens and refresh tokens. Store it somewhere that your C# program can read from and write to (e.g. a file or database)

  10. The realmID is available from Step 3. 'Make API calls'. (Record this for use in your C# program as it doesn't change)

  11. Add the IppDotNetSdkForQuickBooksApiV3 NuGet package to your C# program. To provide easy access to the API.

  12. Make sure you're using .Net Framework 4.6.1 or later because QBO requires TLS 1.2 connections

  13. Unfortunately, .Net console apps don't use TLS 1.2 by default. Therefore add this line of code somewhere in your C# program's startup:

    // Have to explicitly set TLS 1.2 as QBO APIs require it
    System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
    

Before accessing the API you'll need code like this to get an access token:

public static string GetAccessToken()
{
    var oauth2Client = new OAuth2Client(CLIENTID_FROM_STEP_2, 
            CLIENT_SECRET_FROM_STEP_2,
            // Redirect not used but matches entry for app
            "https://developer.intuit.com/v2/OAuth2Playground/RedirectUrl",
            "production"); // environment is “sandbox” or “production”

    var previousRefreshToken = ReadRefreshTokenFromWhereItIsStored();
    var tokenResp = oauth2Client.RefreshTokenAsync(previousRefreshToken );
    tokenResp.Wait();
    var data = tokenResp.Result;

    if ( !String.IsNullOrEmpty(data.Error) || String.IsNullOrEmpty(data.RefreshToken) || 
          String.IsNullOrEmpty(data.AccessToken))
    {
        throw new Exception("Refresh token failed - " + data.Error);
    }

    // If we've got a new refresh_token store it in the file
    if (previousRefreshToken != data.RefreshToken)
    {
        Console.WriteLine("Writing new refresh token : " + data.RefreshToken);
        WriteNewRefreshTokenToWhereItIsStored(data.RefreshToken)

    }
    return data.AccessToken;
}

You'll need to write the functions ReadRefreshTokenFromWhereItIsStored() and WriteNewRefreshTokenToWhereItIsStored() to load and save the refresh token from persistent storage.

All API access in QBO starts with a Service Context. You can create one with code like this:

static public ServiceContext GetServiceContext()
{
    var accessToken = GetAccessToken(); // Code from above
    var oauthValidator = new OAuth2RequestValidator(accessToken);

    ServiceContext qboContext = new ServiceContext(REALMID_PROD_FROM_STEP10,
            IntuitServicesType.QBO, oauthValidator);

    return qboContext;
}

The to access data you can create a data service like this:

var service = new DataService(GetServiceContext());
like image 114
mpipe3 Avatar answered Nov 10 '22 00:11

mpipe3