Sample code for 30+ languages & platforms
Java Requires Chilkat v11.0.0+

QuickBooks - Automatically Refresh Access Token with No User Interaction

See more QuickBooks Examples

Demonstrates how to automaticaly refresh an expired access token and retry the request after a 401 authorization error.

Chilkat Java Downloads

Chilkat2 Java
import com.chilkatsoft.chilkat2.ChilkatException;
import com.chilkatsoft.chilkat2.DateTime;
import com.chilkatsoft.chilkat2.DtObj;
import com.chilkatsoft.chilkat2.JsonObject;
import com.chilkatsoft.chilkat2.OAuth2;
import com.chilkatsoft.chilkat2.Rest;
import com.chilkatsoft.chilkat2.StringBuilder;

public class ChilkatExample {

    public static void main(String[] args) {
        // This example assumes the Chilkat API to have been previously unlocked.
        // See Global Unlock Sample for sample code.

        // Get our previously obtained OAuth2 access token, which should contain JSON like this:
        // {
        //   "expires_in": 3600,
        //   "x_refresh_token_expires_in": 8726400,
        //   "refresh_token": "L011546037639r ... 3vR2DrbOmg0Sdagw",
        //   "access_token": "eyJlbmMiOiJBMTI4Q0 ... oETJEMbeggg",
        //   "token_type": "bearer"
        // }

        JsonObject jsonToken = new JsonObject();
        jsonToken.loadFile("qa_data/tokens/qb-access-token.json");

        Rest rest = new Rest();

        // Connect using TLS.
        // A single REST object, once connected, can be used for many Quickbooks REST API calls.
        // The auto-reconnect indicates that if the already-established HTTPS connection is closed,
        // then it will be automatically re-established as needed.
        boolean bAutoReconnect = true;
        try {
            rest.connect("sandbox-quickbooks.api.intuit.com", 443, true, bAutoReconnect);
        } catch (ChilkatException e) {
            System.out.println(e.getLastErrorText());
            return;
        }

        StringBuilder sbAuth = new StringBuilder();
        sbAuth.append("Bearer ");
        sbAuth.append(jsonToken.stringOf("access_token"));
        rest.setAuthorization(sbAuth.getAsString());

        rest.addHeader("Accept", "application/json");
        rest.setAllowHeaderFolding(false);

        // The company ID is 123146096291789
        // The employee ID is 58
        String responseBody;
        try {
            responseBody = rest.fullRequestNoBody("GET", "/v3/company/123146096291789/employee/58?minorversion=45");
        } catch (ChilkatException e) {
            System.out.println(e.getLastErrorText());
            return;
        }

        // If we get a 401 authorization error, then it's likely because the access token expired.
        // We can automatically refresh it without interaction from the user.
        if (rest.getResponseStatusCode() == 401) {
            OAuth2 oauth2 = new OAuth2();

            oauth2.setTokenEndpoint("https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer");

            // Replace these with actual values.
            oauth2.setClientId("QUICKBOOKS-CLIENT-ID");
            oauth2.setClientSecret("QUICKBOOKS-CLIENT-SECRET");

            // Get the "refresh_token"
            oauth2.setRefreshToken(jsonToken.stringOf("refresh_token"));

            // Send the HTTP POST to refresh the access token..
            try {
                oauth2.refreshAccessToken();
            } catch (ChilkatException e) {
                System.out.println(e.getLastErrorText());
                return;
            }

            System.out.println("New access token: " + oauth2.getAccessToken());

            // Update the JSON with the new tokens.
            jsonToken.updateString("access_token", oauth2.getAccessToken());

            // Save the new JSON access token response to a file.
            // The access + refresh tokens contained in this JSON will be needed for the next refresh.
            StringBuilder sbJson = new StringBuilder();
            jsonToken.setEmitCompact(false);
            jsonToken.emitSb(sbJson);
            sbJson.writeFile("qa_data/tokens/qb-access-token.json", "utf-8", false);

            System.out.println("OAuth2 token refreshed!");
            System.out.println("New Access Token = " + oauth2.getAccessToken());

            sbAuth.clear();
            sbAuth.append("Bearer ");
            sbAuth.append(oauth2.getAccessToken());
            rest.setAuthorization(sbAuth.getAsString());

            // Now retry the request with the refreshed access token...
            try {
                responseBody = rest.fullRequestNoBody("GET", "/v3/company/123146096291789/employee/58?minorversion=45");
            } catch (ChilkatException e) {
                System.out.println(e.getLastErrorText());
                return;
            }
        }

        // We should expect a 200 response if successful.
        if (rest.getResponseStatusCode() != 200) {
            System.out.println("Request Header: ");
            System.out.println(rest.getLastRequestHeader());
            System.out.println("----");
            System.out.println("Response StatusCode = " + rest.getResponseStatusCode());
            System.out.println("Response StatusLine: " + rest.getResponseStatusText());
            System.out.println("Response Header:");
            System.out.println(rest.getResponseHeader());
            System.out.println(responseBody);
            return;
        }

        // Load the JSON response into a JSON object for parsing.
        // A sample JSON response is shown below.
        JsonObject json = new JsonObject();
        json.load(responseBody);

        // These will be used for parsing date/time strings..
        DateTime dtime = new DateTime();
        boolean bLocalTime = true;

        // Show the JSON.
        json.setEmitCompact(false);
        System.out.println(json.emit());

        // Get some information from the JSON..
        System.out.println("Name: " + json.stringOf("Employee.DisplayName"));
        System.out.println("Id: " + json.stringOf("Employee.Id"));
        System.out.println("City: " + json.stringOf("Employee.PrimaryAddr.City"));
        System.out.println("PostalCode: " + json.stringOf("Employee.PrimaryAddr.PostalCode"));

        // Load the CreateTime into a CkDateTime...
        dtime.setFromTimestamp(json.stringOf("Employee.MetaData.CreateTime"));
        DtObj dt = new DtObj();
        dtime.toDtObj(bLocalTime, dt);

        System.out.println(dt.getMonth() + "/" + dt.getDay() + "/" + dt.getYear() + "  " + dt.getHour() + ":" + dt.getMinute());

        System.out.println("Success.");

        // Use this online tool to generate parsing code from sample JSON:
        // Generate Parsing Code from JSON

        // ------------------------------------------------------
        // The JSON response looks like this:

        // {
        //   "Employee": {
        //     "SSN": "XXX-XX-XXXX",
        //     "PrimaryAddr": {
        //       "Id": "116",
        //       "Line1": "45 N. Elm Street",
        //       "City": "Middlefield",
        //       "CountrySubDivisionCode": "CA",
        //       "PostalCode": "93242"
        //     },
        //     "BillableTime": false,
        //     "domain": "QBO",
        //     "sparse": false,
        //     "Id": "98",
        //     "SyncToken": "0",
        //     "MetaData": {
        //       "CreateTime": "2015-07-24T09:34:35-07:00",
        //       "LastUpdatedTime": "2015-07-24T09:34:35-07:00"
        //     },
        //     "GivenName": "Bill",
        //     "FamilyName": "Miller",
        //     "DisplayName": "Bill Miller",
        //     "PrintOnCheckName": "Bill Miller",
        //     "Active": true,
        //     "PrimaryPhone": {
        //       "FreeFormNumber": "234-525-1234"
        //     }
        //   },
        //   "time": "2015-07-24T09:35:54.805-07:00"
        // }
    }
}