Search code examples
phphttpcurlquickbooksintuit-partner-platform

Quickbooks php curl authenticated GET request fails


I have set up a company in the QuickBooks developer portal, and have successfully created an OAuth token (which I can refresh as specified in this answer). So, unlike the majority of these questions, this is not about OAuth... I'm using bare PHP here, as I cannot use the SDK for technical reasons.

After getting the OAuth token, I am trying to perform the next API call from the API playground, getting the company information. I effectively call the QB API with this code:

($query is /v3/company/<companyID>/companyinfo/<companyID> (companyID is the "Realm ID" from the API playground), $base is the sandbox-URL (same as "Sandbox Base URL" in the header), $access_tokens["access"] is the OAuth access token; $url is https://${base}${query})

$headers = array(
    "GET " . $query . " HTTP/2",
    "Host: " . $base,
    "Accept: application/json",
    "Authorization: Bearer " . $access_tokens["access"],
    "Production Base URL: https://quickbooks.api.intuit.com",
    "Sandbox Base URL: https://sandbox-quickbooks.api.intuit.com"
);

$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
curl_setopt($curl, CURLOPT_HEADER, true);
$output = curl_exec($curl);

After the call, the value of $output is:

HTTP/2 400 
date: Tue, 31 Aug 2021 14:42:55 GMT
content-type: text/plain
content-length: 11
server: envoy

Bad Request

The request headers (as returned by the QB server via curl_getinfo) are:

GET /v3/company/4...0/companyinfo/4...0 HTTP/2
Host: sandbox-quickbooks.api.intuit.com
accept: application/json
authorization: Bearer e...Q
production base url: https://quickbooks.api.intuit.com
sandbox base url: https://sandbox-quickbooks.api.intuit.com

(the auth token and company ID have been cut)

If I call the URL directly in a browser, I get a 401 (authentication error) as expected, so I assume the OAuth part works (as I said, I can successfully retrieve an access token and refresh it). I'm just wondering if there is anything else that I'm doing wrong which causes the QB API call to fail?


Solution

  • There's a lot here that looks a little funky... I would start by trying these things:

    • Removing the invalid GET header. GET is not a valid HTTP header (it's part of the method/verb instead), and you shouldn't be trying to specify HTTP/2 in this way. Remove this:
    "GET " . $query . " HTTP/2",
    
    • Remove the two other invalid HTTP headers. It looks like you're confusing Intuit's documentation for HTTP headers here. These are not valid headers and you should not be sending them:
    "Production Base URL: https://quickbooks.api.intuit.com",
    "Sandbox Base URL: https://sandbox-quickbooks.api.intuit.com"
    
    • Don't specify the Host: header to cURL. There's no reason to, and it could potentially conflict with the URL you pass cURL. cURL will calculate and send this for you.
    "Host: " . $base,
    

    I'd also check tomake sure you're sending the request to the correct URL. If it's for a sandbox company, it goes to the sandbox URL. If it's for a production company, it goes to the production URL.