intuit / quickbooks-v3-dotnet-sdk Goto Github PK
View Code? Open in Web Editor NEW.Net SDK for QuickBooks REST API v3 services
License: Apache License 2.0
.Net SDK for QuickBooks REST API v3 services
License: Apache License 2.0
I just updated from the 4.x SDK to the 5.6 SDK package and found some changed behavior that is causing us problems.
We pull down invoices using the QueryService. Once we have an invoice, we loop through the line items, looking for only those that have a DetailType equal to LineDetailTypeEnum.SalesItemLineDetail. The problem occurs when a line item has no Product/Service assigned to it. In the 4.x SDK, the line item's DetailType is set as DescriptionOnly. In the 5.6 SDK, the DetailType is SalesItemLineDetail. I believe the previous behavior is correct.
Not only does the new SDK assign the DetailType incorrectly, but the ItemRef property also seems to be incorrectly assigned to the first/default value that our QB instance uses. It should have no ItemRef as far as I know, and certainly not the one being reported.
I get a null reference exception from the ServiceContext
constructor, from within the GetBaseURL
method.
It looks like this code isn't handling the scenario where the BaseUrl.Qbo value starts out as null (instead of the empty string):
https://github.com/intuit/QuickBooks-V3-DotNET-SDK/blob/master/IPPDotNetDevKitCSV3/Code/Intuit.Ipp.Core/ServiceContext.cs#L390
https://github.com/intuit/QuickBooks-V3-DotNET-SDK/blob/master/IPPDotNetDevKitCSV3/Code/Intuit.Ipp.DataService/Batch.cs has value "25" as max allowed batch items.
Why this value used? Here is no such value https://developer.intuit.com/docs/api/accounting/batch
Is that in the upcoming plans?
"OtherPrefs": {
"NameValue": [
{
"Name": "SalesFormsPrefs.DefaultCustomerMessage",
"Value": "Thank you for your business and have a great day!"
},
{
"Name": "SalesFormsPrefs.DefaultItem",
"Value": "19"
},
{
"Name": "DTXCopyMemo",
"Value": "true"
},
{
"Name": "UncategorizedAssetAccountId",
"Value": "125"
},
{
"Name": "UncategorizedIncomeAccountId",
"Value": "123"
},
{
"Name": "UncategorizedExpenseAccountId",
"Value": "124"
},
{
"Name": "SFCEnabled",
"Value": "true"
},
{
"Name": "DataPartner",
"Value": "false"
},
{
"Name": "Vendor1099Enabled",
"Value": "true"
},
{
"Name": "TimeTrackingFeatureEnabled",
"Value": "true"
},
{
"Name": "FDPEnabled",
"Value": "false"
},
{
"Name": "ProjectsEnabled",
"Value": "true"
}
]
},
Hi, first of all thanks for doing a great job with this SDK.
I can't however find a way to get the totalCount
response from the query endpoint using the Batch.Execute() method, when passing in a query that has a SELECT Count(*) clause. Am I going about this the wrong way?
Here's the full code I use:
`Batch batch = ConnectionCache.GetQBODataService(qboCredentials).CreateNewBatch();
batch.Add(query, batchId);
batch.Execute();
if (batch.IntuitBatchItemResponses != null && batch.IntuitBatchItemResponses.Count() > 0)
{
IntuitBatchResponse response = batch.IntuitBatchItemResponses.FirstOrDefault(item => item.Id == batchId);`
IntuitBatchResponse has a response but the response has Entity = null and Entities.Count = 0. No other property with the totalCount from the QuickBooks response. See image from Fiddler
attached.
Add strong name to assemblies
This is similar to issue #50 but more specific to hosting in azure via app services.
ASP.NET Core 2.x apps do not use the web.config file and when hosting in azure, the build autogenerates the web.config file with no good support for manipulating it to add stuff so you just get the default one that hosts the app.
Currently, the ServiceContext internally news up a configuration reader that only looks for configuration section of web config. Please add support to change how / where configuration information is provided. Because of the current implementation, we have no way to override the baseUrl to point to development sandbox; it's always pointing to production service.
In the meantime, I'm going to fork this project and include the ability to read the baseUrl from appSettings.json / Environment Variables (used by Azure app services).
Could not load file or assembly 'Intuit.Ipp.Retry, Version=5.1.2.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
File name: 'Intuit.Ipp.Retry, Version=5.1.2.0, Culture=neutral, PublicKeyToken=null'
I can see (https://github.com/intuit/QuickBooks-V3-DotNET-SDK/blob/master/IPPDotNetDevKitCSV3/Code/Intuit.Ipp.DataService/Batch.cs#L605) only CDCResponse.entities
filled. How to work with exceptions in case of CDC query?
I tried with customers and bills and it seems to happen no matter what.
But when FindAllAsync
returns it does not have any data:
The logs show a huge response that somehow doesn't make it to the async callback:
Trace logs look pretty normal:
A couple other people seem to have had this issue as well:
https://help.developer.intuit.com/s/question/0D5G000004Dk723KAB/data-service-async-call-doesnt-respond-entities
https://help.developer.intuit.com/s/question/0D50f00004zqoZwCAI/findallasync-for-customer-doesnt-work-properly-c
On the second one @nimisha84 mentioned a question here on GitHub but I can't seem to locate that question.
Hello, my name is Brock Allen and I am the co-author/co-owner of the IdentityModel project, whose main repository resides here https://github.com/IdentityModel/IdentityModel2.
It has come to my attention that a commit to this repository, controlled by Intuit, seems to contain files that were originally from the IdentityModel2 project. The manner in which the files were copied and modified violates the license of the IdentityModel2 project (as well as copyrights held by Microsoft included in the IdentityModel2 project). The commit to this repository is here:
While the files do not match exactly those from the IdentityModel2 project, there are many striking similarities such as directory structure, file names, executable source code, unit tests, and code comments that are an exact match. The modifications performed to the original files are mostly cosmetic and include namespace changes, variable name changes, rewording comments, and replacing the copyright ownership notices themselves. Below are two file diffs that illustrate some of these similarities and modifications.
While IdentityModel2 uses the Apache 2 license, which is a permissive free software license, it does state in sections 4b and 4c (https://github.com/IdentityModel/IdentityModel2/blob/dev/LICENSE#L97-L104) that:
On behalf of the owners of the IdentityModel project, I kindly request that Intuit remedy this copyright violation by either removing the files, or by adhering to the license agreement.
Today QB was returning html page for API requests:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
<title>
We'll be back soon
</title>
...
and SDK was unable to generate high-level exception like "Server not working":
Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value: <. Path '', line 0, position 0.
в Newtonsoft.Json.JsonTextReader.ParseValue()
в Newtonsoft.Json.JsonTextReader.Read()
в Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter)
в Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
в Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
в Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
в Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
в Intuit.Ipp.Utility.JsonObjectSerializer.Deserialize[T](String message)
в Intuit.Ipp.QueryFilter.QueryService`1.ExecuteIdsQuery(String idsQuery, QueryOperationType queryOperationType)
I'm experiencing the same issue as this person:
It appears that the Quickbooks API Nuget package causes V9 to be referenced as well as V10, preventing package upgrades.
I'm getting this error in y'alls code:
Newtonsoft.Json.JsonReaderException: Error reading JObject from JsonReader. Current JsonReader item is not an object: Null. Path 'Fault', line 1, position 29.
at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader, JsonLoadSettings settings)
at Intuit.Ipp.Utility.IntuitConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)
at Intuit.Ipp.Utility.IntuitConverter.AssignValueToProperty(Object target, JProperty prop, Type type, String propName, JsonSerializer serializer)
at Intuit.Ipp.Utility.IntuitConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at Intuit.Ipp.Utility.JsonObjectSerializer.Deserialize[T](String message)
at Intuit.Ipp.DataService.Batch.Execute()
It started for certain company files of ours at 1AM PST this morning.
When I do
reportService.ExecuteReport("AgedReceivables");
I get
Intuit.Ipp.Exception.SerializationException: Object reference not set to an instance of an object. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at Intuit.Ipp.Utility.ObjectToEnumConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)
at Intuit.Ipp.Utility.IntuitConverter.AssignValueToProperty(Object target, JProperty prop, Type type, String propName, JsonSerializer serializer)
at Intuit.Ipp.Utility.IntuitConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)
at Intuit.Ipp.Utility.IntuitConverter.AssignValueToProperty(Object target, JProperty prop, Type type, String propName, JsonSerializer serializer)
at Intuit.Ipp.Utility.IntuitConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.Serialization.JsonSerializerProxy.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.Linq.JToken.ToObject(Type objectType, JsonSerializer jsonSerializer)
at Intuit.Ipp.Utility.IntuitConverter.AssignValueToProperty(Object target, JProperty prop, Type type, String propName, JsonSerializer serializer)
at Intuit.Ipp.Utility.IntuitConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at Intuit.Ipp.Utility.JsonObjectSerializer.Deserialize[T](String message)
--- End of inner exception stack trace ---
at Intuit.Ipp.Exception.IdsExceptionManager.HandleException(IdsException idsException)
at Intuit.Ipp.Utility.JsonObjectSerializer.Deserialize[T](String message)
at Intuit.Ipp.ReportService.ReportService.ExecuteReport(String reportName)
Happening on RealmId 193514831343224
Using Invoice invoice = new Invoice();
Error : There was an error reflecting type 'Intuit.Ipp.Data.Invoice'.
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
at Intuit.Ipp.Utility.XmlObjectSerializer.Serialize(Object entity)
Hi - since I upgraded the Nuget package to 5.2, I found that Intuit.Ipp.Retry.dll was not being copied along to the output exe folder of my project, and so I consistently get a runtime failure on running a report (ReportService.ExecuteReport, say).
System.IO.FileNotFoundException: Could not load file or assembly 'Intuit.Ipp.Retry, Version=5.1.2.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
It was OK up to now - have I missed something I'm supposed to be doing since the upgrade? Or is this some crazy Nuget thing?
I am having trouble compiling IppDotNetDevKitCSV3.sln. I’m not sure but I’m guessing it is because of circular references. For example, Intuit.Ipp.Core references Intuit.Ipp.Retry which in turn references Intuit.Ipp.Core. Do you have any suggestions? Thanks.
Occurs when you do parallel requests because of this line https://github.com/intuit/QuickBooks-V3-DotNET-SDK/blob/master/IPPDotNetDevKitCSV3/Code/Intuit.Ipp.Core/LogRequestsToDisk.cs#L93
it is safe to use FileMode.Append
instead (other option - overwrite - will hide some data)
Setting ServicePointManager.SecurityProtocol to TLS 1.2 affects on whole Application Domain and breaks all the other requests and network - based APIs from application that don't support TSL 1.2.
Sometimes theese APIs use default settings and your code breaks them.
In the files AsyncRestHandler.cs, SyncRestHandler.cs there is a following line
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
This sets security protocol to TLS 1.2 for the whole application, and breaks the requests to services that don't support TLS1.2. The appropriate security protocol is selected automatically while connecting to endpoint, so this code can be safely removed. In order to use TLS 1.2 explicity to enforce protocol selection please use the following code
var httpClientHandler = new HttpClientHandler { SslProtocols =SslProtocols.Tls12 }; httpClient = new HttpClient(httpClientHandler, disposeHandler: true);
Setting SecurityProtocol via Handler is inapplicable for HttpWebRequest so it should be replaced with HttpClient.
When we try to create a quickbooks online item, we get a business validation error with below description -
Business Validation Error: When you create an item, if Track quantity on hand is turned off, the item cannot be of type Inventory.
We do have "track inventory quantity on hand" setting on so this shouldn't be occurring. Would be great if you could look into it?
I have question. How do you build this solution? Are there instructions somewhere on how to build it? I downloaded the source and can't build it in VS2017 because of multiple circular references. For example Ipp.Rety references Ipp.Core and Ipp.Core references Ipp.Retry and many others like that. What am I missing?
I ran into an issue while trying to use the OAuth2Client.GetBearerTokenAsync
method. We are in an ASP.NET synchronous code base, and when we attempt to use .GetAwaiter().GetResult()
to fetch the token response, the call never returns, and the thread hangs forever.
I believe my specific issue can be fixed by adding ConfigureAwait(false)
to the following line in https://github.com/intuit/QuickBooks-V3-DotNET-SDK/blob/master/IPPDotNetDevKitCSV3/Code/Intuit.Ipp.OAuth2PlatformClient/Client/OAuth2Client.cs#L138
This is based on the article I've listed below. I think it would be worthwhile to add ConfigureAwait(false)
to all of the exposed async methods and make sure each awaited method in the call stack also uses ConfigureAwait(false)
http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html
I want to properly handle all possible exception from SDK, but some of them never used in code:
Are they all was used before, but will not be used in future?
var oauthValidator = new OAuth2RequestValidator(oauthInfo.AccessToken);
var serviceContext = new ServiceContext(oauthInfo.RealmId, IntuitServicesType.QBO, oauthValidator);
var dataService = new DataService(serviceContext);
serviceContext.RequestId = GuidGenerator.GenerateGuid();
var customer = new Customer {
GivenName = "QQQ",
Title = "WWW",
MiddleName = "EEE",
FamilyName = "AAA"
};
var result = dataService.Add(customer) as Customer;
Exception throw in the last line: Invalid URI: The format of the URI could not be determined.
StackTrace:
at System.Uri.CreateThis(String uri, Boolean dontEscape, UriKind uriKind)
at System.Uri..ctor(String uriString)
at Intuit.Ipp.Core.Rest.RestHandler.PrepareRequest(RequestParameters requestParameters, Object requestBody, String oauthRequestUri, Boolean includeRequestId)
at Intuit.Ipp.Core.Rest.SyncRestHandler.PrepareRequest(RequestParameters requestParameters, Object requestBody, String oauthRequestUri, Boolean includeRequestId)
at Intuit.Ipp.DataService.DataService.Add[T](T entity)
at ClothResorting.Helpers.IntuitOAuthor.GetAllCustomer(String userId) in d:\users\downw\onedrive\documents\visual studio 2015\Projects\ClothResorting\ClothResorting\Helpers\IntuitOAuthor.cs:line 172
at ClothResorting.Controllers.Api.QuickBooksOnlineOAuthController.SyncInvoiceToQBO(Int32 id) in d:\users\downw\onedrive\documents\visual studio 2015\Projects\ClothResorting\ClothResorting\Controllers\Api\QuickBooksOnlineOAuthController.cs:line 80
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_1.b__3(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)
============
I have valid access_Token and successfully built OAuth2RequestValidato
and ServiceContext
. Is there any possibility that was caused by string encode? If so how could I fix it because I cannot touch the Add()
method?
I get an error Append access can be requested only in write-only mode.
with the following set to true:
<intuit> <ipp> <logger> <!-- To enable/disable Request and Response log--> <requestLog enableRequestResponseLogging="true" requestResponseLoggingDirectory="Z:\WWW\PM\Logs" xdt:Transform="Replace"/> </logger> </ipp> </intuit> <intuit> <ipp> <logger> <!-- To enable/disable Request and Response log--> <requestLog enableRequestResponseLogging="true" requestResponseLoggingDirectory="Z:\WWW\PM\Logs" xdt:Transform="Replace"/> </logger> </ipp> </intuit>
.NET internally stores strings encoded as UTF-16 but QBO expects UTF-8. The two encodings are the same for all single-byte code points so you tend not to notice when you aren't sending special characters to QBO. But, for queries with special characters you must put all strings through the following filter (I wrote it as an extension method for kicks):
public static string ToUtf8(this string input) =>
new string(Encoding.UTF8.GetBytes(input).Select(b => (char)b).ToArray());
Following the principle of least astonishment, this should be done by the SDK.
package dependencies has typo in 7.2.0. This has dependency in Microsoft.Net.Compliers. Should be Microsoft.Net.Compilers
DiscoveryClient
does not handle the TLS1.2 properly.
My project framework is on 4.7.1, and I have 4.7.2 installed on my computer. It works great.
Another developer does not have 4.7.2 so the TLS seems to be incorrect.
new OAuth2Client(clientId, clientSecret, redirectUrl, "sandbox").GetAuthorizationURL(scopes);
Actual
?client_id=ABC&response_type=code&scope=com.intuit.quickbooks.accounting&redirect_uri=http%3A%2F%2Flocalhost%3A27353%2Fcallback&state=DEF
Expected
https://appcenter.intuit.com/connect/oauth2?client_id=ABC&response_type=code&scope=com.intuit.quickbooks.accounting&redirect_uri=http%3A%2F%2Flocalhost%3A27353%2Fcallback&state=DEF
OR
throw an exception immediately instead of failing silently. Calling GetBearerTokenAsync
will throw a null exception if the TLS is incorrect.
Workaround
Set the SecurityProtocol
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Hi.
I am getting an ArgumentException when calling DataService.CDCAsync.
Intuit.Ipp.Exception.IdsException: An item with the same key has already been added.
This seems to happen due a difference between the synchronous CDC call and the asynchronous CDCAsync handler. When multiple entities of a common type are returned by the CDC, the repeated add into the returnValue Dictionary causes the error.
CDCAsync (causes error)
object[] tempEntityArray = (object[])tempEntities;
if (tempEntityArray.Length > 0)
{
foreach (object item in tempEntityArray)
{
entities.Add((IEntity)item);
returnValue.Add(item.GetType().Name, entities);
count++; // this line appears unused
}
}
CDC (works correctly)
object[] tempEntityArray = (object[])tempEntities;
if (tempEntityArray.Length > 0)
{
List<IEntity> arr = new List<IEntity>(); // this line appears unused
string entityName = string.Empty;
foreach (object item in tempEntityArray)
{
entities.Add((IEntity)item);
entityName = item.GetType().Name;
}
returnValue.entities.Add(entityName, entities);
}
What is the rationale of using binary references within the project definitions e.g.
<Reference Include="Intuit.Ipp.Core, Version=5.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\SDK Assemblies\Intuit.Ipp.Core.dll</HintPath>
</Reference>
It makes compiling the SDK a nightmare with a lot of workarounds, you are shipping the entire library as one nuget package anyway so it can't be dependency versioning?
There is some conversion from ctor argument to both Url and Authority:
Default Policy.ValidateIssuerName
is true, so I expect that either new DiscoveryClient("https://developer.intuit.com/.well-known/openid_sandbox_configuration/")
or new DiscoveryClient("https://oauth.platform.intuit.com/op/v1")
should work.
But there is no https://oauth.platform.intuit.com/op/v1/.well-known/openid_sandbox_configuration/, and https://developer.intuit.com does not match Issuer (https://oauth.platform.intuit.com/op/v1).
There is also very interesting commented
So why DiscoveryClient.Authority ever exists?
Batch
use IterateFaultAndPrepareException()
- copypaste from FaultHandler
- to prepare exceptions from separate BatchItemResponse
s.
From source code it is obvious that IntuitBatchResponse.Exception
could contain Service and Auth exceptions. But isn't such exception would be thrown during execution of batch, at restHandler.GetResponse(request);
?
The Nuget description lists support for Azure logging, but as far as we know that's not the case.
https://www.nuget.org/packages/IppDotNetSdkForQuickBooksApiV3/
We asked about this a year ago, and imagine other cloud developers have the same requirement. We need to be able to catch error responses in a cloud environment.
Application: MyService.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.NullReferenceException at Intuit.Ipp.DataService.Batch.BatchAsyncompleted(System.Object, Intuit.Ipp.Core.AsyncCallCompletedEventArgs) at Intuit.Ipp.Core.Rest.AsyncRestHandler.AsyncExecutionCompleted(System.IAsyncResult) at System.Net.LazyAsyncResult.Complete(IntPtr) at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) at System.Net.ContextAwareResult.Complete(IntPtr) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr) at System.Net.HttpWebRequest.SetResponse(System.Exception) at System.Net.ConnectionReturnResult.SetResponses(System.Net.ConnectionReturnResult) at System.Net.Connection.ReadComplete(Int32, System.Net.WebExceptionStatus) at System.Net.LazyAsyncResult.Complete(IntPtr) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr) at System.Net.AsyncProtocolRequest.CompleteWithError(System.Exception) at System.Net.FixedSizeReader.ReadCallback(System.IAsyncResult) at System.Net.LazyAsyncResult.Complete(IntPtr) at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object) at System.Net.ContextAwareResult.Complete(IntPtr) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr) at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
QBO wants to see a property called "UnitPrice" on the json to create new Sales Receipts and the QBO .NET library puts a property called "PriceLevelRef" there instead. The same issue seems to plague Invoices as well, and probably more stuff.
We've discovered this very unusual issue using version 5.5 of this project from nuget.
The following code works locally:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; //Add this just to be sure to use TLS1.2
realmId = Session["realm"].ToString();
accessToken = Session["accessToken"].ToString();
accessTokenSecret = Session["accessTokenSecret"].ToString();
consumerKey = ConfigurationManager.AppSettings["consumerKey"].ToString();
consumerSecret = ConfigurationManager.AppSettings["consumerSecret"].ToString();
dataSourcetype = Session["dataSource"].ToString().ToLower();
try
{
var intuitServicesType = new IntuitServicesType();
intuitServicesType = IntuitServicesType.QBO;
var oauthValidator = new OAuthRequestValidator(accessToken, accessTokenSecret, consumerKey, consumerSecret);
var context = new ServiceContext(realmId, intuitServicesType, oauthValidator);
context.IppConfiguration.BaseUrl.Qbo = _qboBaseURL;
var dataService = new DataService(context);
var company = new Company();
var cmps = dataService.FindAll(company);
When deploying the code to Windows 2012 R2 standard with Framework 4.7.1 installed, the last line var cmps = dataService.FindAll(company);
Throws the following error:
System.MissingMethodException: Method not found: 'System.Net.HttpWebRequest Intuit.Ipp.Core.Rest.IRestHandler.PrepareRequest(Intuit.Ipp.Core.Rest.RequestParameters, System.Object, System.String)'. at Intuit.Ipp.DataService.DataService.FindAll[T](T entity, Int32 startPosition, Int32 maxResults)
The web app is published to a file directory and has been deployed and tested in both debug and release mode.
The web app targets 4.7.1 (in [Project] > Properties > Application).
Verified that Intuit.Ipp.Core.dll is in the /bin directory and is version 5.5.0.0
Callback
Code: none
State: e542d83e1b61425db569ea956c2df730 (valid)
RealmId: none
Error: invalid_scope
Note:SIWI flow does not returns relamId as it does not have the required scopes
Not sure what further configuration is to be done here.
When I create an Invoice via the Quickbooks UI, I have an option to allow Free ACH Payment.
When I create the same invoice via the Quickbooks SDK, I there are options for:
AllowOnlineACHPayment
and
allowCreditCard
Setting those to true does not result in the ACH option to be enabled.
I have also tried setting: AllowOnlineACHPaymentSpecified to true as well.
Here is a code snippit:
`if(invoice.FleetPilot.FleetPilotGroup.allowACH || invoice.FleetPilot.FleetPilotGroup.allowCreditCard)
{
newInvoice.AllowIPNPayment = true;
newInvoice.AllowIPNPaymentSpecified = true;
newInvoice.AllowOnlinePayment = true;
newInvoice.AllowOnlinePaymentSpecified = true;
}
newInvoice.AllowOnlineACHPayment = invoice.FleetPilot.FleetPilotGroup.allowACH;
newInvoice.AllowOnlineACHPaymentSpecified = invoice.FleetPilot.FleetPilotGroup.allowACH;
newInvoice.allowCreditCard = invoice.FleetPilot.FleetPilotGroup.allowCreditCard;
newInvoice.AllowOnlineCreditCardPaymentSpecified = invoice.FleetPilot.FleetPilotGroup.allowCreditCard;
var addedInvoice = dataService.Add<Invoice>(newInvoice);
invoice.ExternalID = addedInvoice.Id;
listInvoices.Add(addedInvoice);
if (invoice.FleetPilot.FleetPilotGroup.sendInvoices)
{
dataService.SendEmail<Invoice>(addedInvoice, invoice.FleetPilot.Pilot.EmailAddress);
}`
OAuth2RequestValidator oauthValidator = new OAuth2RequestValidator(systemSettings.AccessToken);
ServiceContext serviceContext = new ServiceContext(systemSettings.RealmId, IntuitServicesType.QBO, oauthValidator);
thows:
Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=0.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
StackTrace:
at Intuit.Ipp.Core.Configuration.LocalConfigReader.ReadConfiguration()
at Intuit.Ipp.Core.ServiceContext..ctor()
at Intuit.Ipp.Core.ServiceContext..ctor(String realmId, IntuitServicesType serviceType, IRequestValidator requestValidator)
at PiMarketing.Controllers.CampaignsController.d__17.MoveNext() in C:\Dev2\Pi_Marketing\PiMarketing\PiMarketing\Controllers\CampaignsController.cs:line 576
Its looking for the old ConfigurationManager that doesn't exist in .NET core
Has this been evaluated?
App integration is running fine using v5.6, but after updating to either v5.7 or v5.8 using Nuget, AuthorizeEndpoint is failing.
"Value cannot be null. Parameter name: endpoint"
"System.ArgumentNullException: at Intuit.Ipp.OAuth2PlatformClient.TokenClient..ctor(String endpoint, HttpMessageHandler innerHttpMessageHandler)
at Intuit.Ipp.OAuth2PlatformClient.TokenClient..ctor(String endpoint, String clientId, String clientSecret, HttpMessageHandler innerHttpMessageHandler, AuthenticationStyle style)
at Intuit.Ipp.OAuth2PlatformClient.TokenClient..ctor(String endpoint, String clientId, String clientSecret, AuthenticationStyle style)
at ServicePal.WebApp.Synchronization.IntuitOAuth2Helper.d__1.MoveNext() in IntuitOAuth2Helper.cs:line 38
Just for kicks I did try:
ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
That makes no difference.
Seems similar to issue #23 but with a different call.
Using ExecuteIdsQuery()
https://quickbooks.api.intuit.com/v3/company/xxxxxx/query?minorversion=21&requestid=xxxxxx
Request Body:
Select * FROM Invoice WHERE MetaData.LastUpdatedTime > '2018-03-24T21:42:59.9658792Z' and MetaData.LastUpdatedTime < '2018-03-26T21:42:59.9147825Z'
However, after deserialization (line 178 in QueryService.cs) - there are no invoices to be found
I have pulled all the latest code from GitHub. Still not working.
Thoughts?
Would be very helpful for the .NET SDK to support .NET core so the SDK can be used cross-platform.
Dependencies to consider:
Assuming the dependency issue is addressed, are there other components within the SDK that would need to be updated/replaced to support .NET core?
https://developer.intuit.com/app/developer/qbo/docs/develop/release-notes/quickbooks-api-release-notes
For v1905 I noticed the following fix
"PLEX-1010 - Fix few V3 entities were not returning proper results when queried for balance and remaining amount"
How do we get more detail on that fix, and what the problem was?
I read between the lines that if 3rd party apps queried customer.balance and stored that value, that perhaps we got an incorrect value.
Is this for QuickBooks-desktop or strictly for QuickBooks-online?
remove lines 331-333 as they are not method parameters
/// <param name="realmId"></param>
/// <param name="access_token"></param>
/// <param name="refresh_token"></param>
line 347 is testing for if (dictionary["access_token"] != null), but param is defined elsewhere (e.g. lines 216-219). Failure to do this results in error "The given key was not present in the dictionary." when sample app is unzipped and configured for the first time.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.