QuickBooks Online query with 401 filter return each time

I managed to create objects using POST and Content-Type application / xml

I also had a successful request using the Content-Type / x-www-form-urlencoded application with an empty request body that returns the entire type of the object, depending on which URI I specify.

I can also get the same to work with something like PageNum = 1 & ResultsPerPage = 1 in the body of the request, and I figured out how to include it in the signature to get a valid response.

However, no matter how I format it, I can get nothing but the 401 answer when I try to use a filter (something basic like Filter = FAMILYNAME: EQUALS: Doe). I read the OAuth Core 1.0 Revision A specs on how all parameter names and values ​​are escaped using percent encoding [RFC3986]. However, I feel like I am missing a step or formatting incorrectly. I saw inconsistent information in my search on Intuit forums on what exactly fits the format.

Any help on this would be greatly appreciated. Now I'm afraid of this good week.

The response I get when I try to use a filter is: HTTP Status 401 - message = OAuth Authentication Exception; ERRORCODE = 003200; StatusCode = 401

---- Update ----

I see the same error when I try to use filters using the New IPP Developer Tools - IPP API API. I am using the QS IDS V2 API. I can use this tool to receive all messages, and the answer shows all my clients, but when I try to use the filter, I get: Server Error 401 - Unauthorized: Access is denied due to invalid credentials. You do not have permission to view this directory or page using the credentials you provided.

Any ideas? If I get the same error from the Explorer tool, it makes me think that the problem is completely different.

---- Final update ----

I finally had success with filters, and I believe that I found out what my problem was. I was always suspicious that I could receive paginated queries, for example "PageNum = 1 & ResultsPerPage = 1", but could not get something like "Filter = FAMILYNAME: EQUALS: Doe". I suspected the problem was with a space in the filter format. What distracted me before was that I couldn't get the filters to work in the QS IDS V2 API. It made me suspect something else was going on. I decided to ignore the Explorer API all together and focus on why I could make it work one way, but not the other.

I believe that my problem boiled down to the incorrect encoding of the filter value in the signature. This explains the 401 invalid signature errors that I received.

"Filter = Name: EQUALS: Doe" becomes "Filter = Name% 20% 3AEQUALS% 20% 3ADoe" after normalization.

Percent encoding, which should give "Filter% 3DName% 2520% 253AEQUALS% 2520% 253ADoe".

In essence, you need to "double" the encoding of a space and a colon, but not an equal sign. I tried many permutations to do the encoding, but I think that my mistake was that I was either not a "double" encoding, or when I was a double encoding, I included the "=" sign. In any case, you violate your signature. Thank you all for your contribution.

+8
quickbooks intuit-partner-platform quickbooks-online
source share
4 answers

I believe that my problem boiled down to the incorrect encoding of the filter value in the signature. This explains the 401 invalid signature errors that I received.

I used an online tool to go through the steps to correctly sign an Oauth request. After going through these steps, I realized that my problem is with how you normalize the query parameters, and then quote them as a percentage. I turned on the filter '=' at the normalization stage, which violates your signature. The tool I used can be found at:

http://hueniverse.com/2008/10/beginners-guide-to-oauth-part-iv-signing-requests/

Thank you all for your contribution.

+2
source share

Do you get 401 with the same request in the API API?

http://ippblog.intuit.com/blog/2013/01/new-ipp-developer-tool-api-explorer.html

Also do you use a static base url or retrieve it at runtime?

https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0400_QuickBooks_Online/0100_Calling_Data_Services/0010_Getting_the_Base_URL

If you are using a static base URL, try switching to the base URL of the runtime to see if you still get the error.

+1
source share

peterl answered one of my questions here, which may also answer your question. I tried to put filters in the body when they were supposed to get into the header. Here is an example peterl code for receiving all unpaid invoices (open balance of more than 0.00) for a specific client.

http://pastebin.com/raw.php?i=7VUB6whp

public List<Intuit.Ipp.Data.Qbo.Invoice> GetQboUnpaidInvoices(DataServices dataServices, int startPage, int resultsPerPage, IdType CustomerId) { StringBuilder requestXML = new StringBuilder(); StringBuilder responseXML = new StringBuilder(); var requestBody = String.Format("PageNum={0}&ResultsPerPage={1}&Filter=OpenBalance :GreaterThan: 0.00 :AND: CustomerId :EQUALS: {2}", startPage, resultsPerPage, CustomerId.Value); HttpWebRequest httpWebRequest = WebRequest.Create(dataServices.ServiceContext.BaseUrl + "invoices/v2/" + dataServices.ServiceContext.RealmId) as HttpWebRequest; httpWebRequest.Method = "POST"; httpWebRequest.ContentType = "application/x-www-form-urlencoded"; httpWebRequest.Headers.Add("Authorization", GetDevDefinedOAuthHeader(httpWebRequest, requestBody)); requestXML.Append(requestBody); UTF8Encoding encoding = new UTF8Encoding(); byte[] content = encoding.GetBytes(requestXML.ToString()); using (var stream = httpWebRequest.GetRequestStream()) { stream.Write(content, 0, content.Length); } HttpWebResponse httpWebResponse = httpWebRequest.GetResponse() as HttpWebResponse; using (Stream data = httpWebResponse.GetResponseStream()) { Intuit.Ipp.Data.Qbo.SearchResults searchResults = (Intuit.Ipp.Data.Qbo.SearchResults)dataServices.ServiceContext.Serializer.Deserialize<Intuit.Ipp.Data.Qbo.SearchResults>(new StreamReader(data).ReadToEnd()); return ((Intuit.Ipp.Data.Qbo.Invoices)searchResults.CdmCollections).Invoice.ToList(); } } protected string GetDevDefinedOAuthHeader(HttpWebRequest webRequest, string requestBody) { OAuthConsumerContext consumerContext = new OAuthConsumerContext { ConsumerKey = consumerKey, ConsumerSecret = consumerSecret, SignatureMethod = SignatureMethod.HmacSha1, UseHeaderForOAuthParameters = true }; consumerContext.UseHeaderForOAuthParameters = true; //URIs not used - we already have Oauth tokens OAuthSession oSession = new OAuthSession(consumerContext, "https://www.example.com", "https://www.example.com", "https://www.example.com"); oSession.AccessToken = new TokenBase { Token = accessToken, ConsumerKey = consumerKey, TokenSecret = accessTokenSecret }; IConsumerRequest consumerRequest = oSession.Request(); consumerRequest = ConsumerRequestExtensions.ForMethod(consumerRequest, webRequest.Method); consumerRequest = ConsumerRequestExtensions.ForUri(consumerRequest, webRequest.RequestUri); if (webRequest.Headers.Count > 0) { ConsumerRequestExtensions.AlterContext(consumerRequest, context => context.Headers = webRequest.Headers); if (webRequest.Headers[HttpRequestHeader.ContentType] == "application/x-www-form-urlencoded") { Dictionary<string, string> formParameters = new Dictionary<string, string>(); foreach (string formParameter in requestBody.Split('&')) { formParameters.Add(formParameter.Split('=')[0], formParameter.Split('=')[1]); } consumerRequest = consumerRequest.WithFormParameters(formParameters); } } consumerRequest = consumerRequest.SignWithToken(); return consumerRequest.Context.GenerateOAuthParametersForHeader(); } 

You can also see my original question here about StackOverflow: Request for all open balance invoices using QuickBooks Online (QBO) Devitit for Intuit Partner (IPP) platform .

+1
source share

I have written about my experience with escaping characters in an OKuth QuickBooks query.

0
source share

All Articles