views:

2136

answers:

3

I am trying to create an ASP.NET page that connects to QuickBooks Online Edition, read a couple of values, and display the results. So far I have downloaded the QuickBooks SDK but I have been unable to find a simple step-by-step example on how to create an asp.net page to connect to QuickBooks Online. The QuickBooks SDK documentation and the SDK itself is very confusing and overwhelming. Anyone know of a simple step by step tutorial on where to get started... or maybe a hint on the very first thing to do.

A: 

The outline of what you have to do are outlined in Chapter 7 of the QBSDK documentation (at least in the 7.0 version of the SDK that I have). You have to open a test account and get permission to connect to their servers.

Once you have your account setup, the basic authentication procedure consists of redirecting your user to the QuickBooks Online site to log in, and once the user has done that, QuickBooks calls back your application with an HTTPS post with a ticket, which is basically a session handle that you can use for your requests, so that the system knows you are authenticated. When you get that response, you parse it and send your own login request to the system based on what you got back.

Then (if I understood the documentation correctly) you are basically doing Https POSTS of xml files with the QuickBooks requests, and you get XML responses that you have to parse to get the data you want.

I hope that gets you started.

The rest of the SDK is documentation (which you will need to know how to form your requests and parse your responses) and everything else is concerned with how to communicate with the desktop product. The only thing you are going to need from the rest of the documentation is how to do error handling, which is really only important if you are posting data to QuickBooks. If you are just reading, it doesn't matter (either your request works out or it doesn't, you don't need to worry about if you need to retry or if that would result in duplicate data).

EDIT: Given your specific use case I see two options. (You aren't crazy, just not the typical QuickBooks Online scenario).

One is to programatically hit up their login page and submit the credentials as if you were a user. I'm sure its not "supported" but it would likely work.

The other is to cache the results (which you should probably do anyway) and have an admin screen where someone does log into QuickBooks online and update the results every morning or evening or whatever makes sense.

In most small businesses, they are going to opt for the first option, but the second one is going to work more consistently, robustly and actually be supported by Intuit if you have an issue.

Yishai
So there is no way to pull data from QuickBooks Online without forcing the individual user to log in to QuickBooks? That just feels incorrect for a user on an ASP.NET application. Which is why I got so confused when reading the SDK documentation (and Chapter 7).
Jeff Widmer
You are going to need credentials. Perhaps you can describe how you are getting those credentials that doesn't require them from the individual user using your site?
Yishai
Can't the ASP.NET application have credentials? I am thinking of QuickBooks Online as just another datasource that I want to access. So just like SQL Server, I have a proper connection string and then I can query the database. ASP.NET does not require each user to authenticate to SQL Server before returning data (well, SQL Server can do that but you rarely would want to). So what is the "ConnectionString" for QuickBooks Online... or am I thinking of QuickBooks Online incorrectly?
Jeff Widmer
Jeff, if this is your *own* QuickBooks instance (not your customers) then I can't imagine why you would use QuickBooks as the datastore to retrieve, but I would love to hear. If, however, this is your user's quickbooks account, then it their data, and every user has a different data instance that has seperate credentials. If this is indeed your own instance, you could attempt to navigate the login page yourself in code. I don't think QuickBooks would support it, but it should work.
Yishai
Here's what we want to do: Display our current net profit for the current month (from QBOE) on an intranet page. Am I crazy to want to do that?
Jeff Widmer
And this is my company's QuickBooks Online instance. All of our employee's have access to the intranet website. The intranet website has NT Authentication for security.
Jeff Widmer
See my post below... you'll need to login when you *very first register the application* but after that your application can connect without using anyone's username or password (it'll just need a connection ticket). What you're wanting to do is a very typical scenario, and it's really not all that difficult to accomplish once you know what you're doing. 95% of the difficulty of working with QuickBooks or QuickBooks Online Edition is the initial set-up, once you get past all that garbage, it's pretty simple.
Keith Palmer
+1  A: 

Yishai's answer is partially correct, but not entirely.

You can have your ASP .NET application log in and issue requests without having to send the user over to the QuickBooks Online log in page if you make sure to set the security preferences correctly when you connect up your application to QuickBooks Online Edition.

During the application registration process/connection process, it will ask you if you want to turn on or off login security with a prompt as below. You must tell it you want to turn off login security if you want to be able to access QuickBooks Online Edition data without forcing the user to log in every time. The prompt is something like:

"Do you want to turn on login security?"

You must select: "No. Anyone who can log into [Application Name] can use the connection".

Outside of that, Yishai is correct about the process. To re-iterate, in a nutshell:

  • Register for a QBOE account
  • Register your integrated application with Intuit's AppReg service
  • Visit a specific link to tie your AppReg application to your QBOE account (make sure you turn off login security when it asks you!)
  • Make HTTPS POST requests to Intuit's servers to sign on using the connection ticket Intuit will provide you with
  • Make HTTPS POST requests to send qbXML requests to Intuit's servers, which you can use to add, modify, delete, and query records within QuickBooks Online Edition.

There is some additional documentation and some example requests on my QuickBooks development and integration wiki, specifically the QuickBooks Online Edition integration page.

I have built a solution that does what you're asking in PHP which adds, modifies, and queries data within QuickBooks Online Edition without requiring the user to log in everytime, and it works like a champ. It pushes and pulls order data between a PHP shopping cart (VirtueMart) and QuickBooks Online Edition. The PHP code is available here: QuickBooks PHP Framework

As a side note, unless you're very familiar with generating SSL certificates and sending them via HTTPS POSTs, you'll save yourself a whole lot of trouble by using the DESKTOP model of communication, and not the HOSTED model. Just make sure to keep your connection ticket securely encrypted.

Also, Yishai's suggestion to: "One is to programatically hit up their login page and submit the credentials as if you were a user. I'm sure its not "supported" but it would likely work." goes specifically against the security/developer guidelines Intuit and the SDK set forth. If they catch you doing that, they'll ban your application from connecting to QuickBooks.

Keith Palmer
See, if you had seen this question a couple of days ago, you would have saved Jeff $85. Now why don't they document the fact that the web site will give you that option in the documentation?
Yishai
Keith, do you have any insight into this question? http://stackoverflow.com/questions/877689/quickbooks-invoice-modify-has-different-address-behavior-than-create-how-to-comp
Yishai
Yeah, Intuit has a bad habit of writing the most ridiculously confusing and over-thought documentation and examples on the face of the planet. Welcome to the wonderful world of QuickBooks integration. :-)
Keith Palmer
Hi Keith, Thank you very much for your help. This is not completely everything I needed but it is close. I found page 68 of the QuickBooks SDK Programmer's Guide which has information about what to do with the connection key once you get it. I am working through that section now.
Jeff Widmer
Jeff Widmer
Looks like it was a QBOE service SDK issue, and that the issue has been resolved now.
Keith Palmer
Still seeing the Bad Request error: See this question since maybe it is my xml: http://stackoverflow.com/questions/1154880/valid-xml-for-posting-to-quickbooks-online-edition-receiving-400-bad-request
Jeff Widmer
Change your qbXML version to 6.0. QuickBooks Online Edition doesn't support 7.0 yet.
Keith Palmer
A: 

Here are all the steps I took to get this working. Special thanks to Keith Palmer for his comments, answers, and his website which really helped me get this working.

  1. Register your application at http://appreg.quickbooks.com. This will give you your App ID and Application Name. I used these settings:

    • Target Application: QBOE
    • Environment: Production
    • Application Type: Desktop

      • (using Desktop made things much easier as far as not needing certificates)
    • A verification key is sent to your email address which you need to enter on page 2 of this wizard.

  2. Set up your QBOE Connection. Once you finish registering your application in Step 1, you will then have an Application ID. Use this ID in the url below to set up your QBOE Connection:
    • https://login.quickbooks.com/j/qbn/sdkapp/confirm?serviceid=2004&appid=APP_ID
    • NOTE: Make sure to replace APP_ID in the above url with the Application ID that was created when you registered your application.
    • The wizard will take you through the following steps:
      1. Specifying a name for your connection.
      2. Granting Access Rights - I gave All Accounting rights since this was easiest.
      3. Specify Login Security - I turned Login Security Off. This is important since it makes submitting the xml to the QBOE much easier since you do not need to get a session ticket for each user.
      4. You will then be given a Connection Key.
  3. At this point you now have the 3 important pieces of information in order to gain access to your QuickBooks Online Edition (QBOE) account.
    • Application Name
    • Application ID
    • Connection Key
  4. Post the XML to QBOE with the 3 pieces of access information and the actual request into your QBOE database. Here is sample c# code that will post to the QBOE gateway. This will return all customers in your QuickBooks database. Make sure to update the xml below with your Application Name, Application ID, and Connection Key.

    string requestUrl = null;
    requestUrl = "https://apps.quickbooks.com/j/AppGateway";
    
    
    HttpWebRequest WebRequestObject = null;
    StreamReader sr = null;
    HttpWebResponse WebResponseObject = null;
    StreamWriter swr = null;
    
    
    try
    {
        WebRequestObject = (HttpWebRequest)WebRequest.Create(requestUrl);
        WebRequestObject.Method = "POST";
        WebRequestObject.ContentType = "application/x-qbxml";
        WebRequestObject.AllowAutoRedirect = false;
    

    string post = @"

    <?xml version=""1.0"" encoding=""utf-8"" ?>
    <?qbxml version=""6.0""?>
    <QBXML>
    <SignonMsgsRq>
    <SignonDesktopRq>
    <ClientDateTime>%%CLIENT_DATE_TIME%%</ClientDateTime>
    <ApplicationLogin>APPLICATION_LOGIN</ApplicationLogin>
    <ConnectionTicket>CONNECTION_TICKET</ConnectionTicket>
    <Language>English</Language>
    <AppID>APP_ID</AppID>
    <AppVer>1</AppVer>
    </SignonDesktopRq>
    </SignonMsgsRq>
    <QBXMLMsgsRq onError=""continueOnError"">
    <CustomerQueryRq requestID=""2"" />
    </QBXMLMsgsRq>
    </QBXML>

    ";

        post = post.Replace("%%CLIENT_DATE_TIME%%", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss"));
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(post);
        post = xmlDoc.InnerXml;
        WebRequestObject.ContentLength = post.Length;
        swr = new StreamWriter(WebRequestObject.GetRequestStream());
        swr.Write(post);
        swr.Close();
        WebResponseObject = (HttpWebResponse)WebRequestObject.GetResponse();
        sr = new StreamReader(WebResponseObject.GetResponseStream());
        string Results = sr.ReadToEnd();
        }
    finally
        {
            try
            {
                sr.Close();
            }
            catch
            {
            }
    
    
    
        try
        {
            WebResponseObject.Close();
            WebRequestObject.Abort();
        }
        catch
        {
        }
    }
    
  5. Couple things to note:

    • As pointed out by Keith Palmer the qbxml version needs to be 6.0 (even though the IDN Unified On-Screen Reference shows 7.0)
    • I needed to include the onError="continueOnError" attribute.
    • Setting the WebRequestObject.ContentLength property is required.
    • Content Type needs to be "application/x-qbxml"
    • And finally I received many "The remote server returned an error: (400) Bad Request." exceptions which were not helpful at all but in the end I was able to trace them to something wrong with the xml. So if you get this exception look to your xml as the source of the problem.
Jeff Widmer
Quick note: You can change the qbXML version within the OSR using the "Max SDK Version" slider on the left.
Keith Palmer
Jeff: You can directly start posting QBXMLs to QB gateway after getting the connection ticket if the Login Security is turned off by the user. If this is true then how will the ASP.NET application know whether to take the user to sessionauth2 url for login/pwd (get session ticket) OR just start POSTing QBXMLs when he hits the SYNC button?
A9S6
Abhimanyu: I would recommend you create a different connection for each of these scenarios. Create a AppLogin/ConnectionTicket for the application that does not use login security and then create another AppLogin/ConnectionTicket for the application that does require login security. Then your application will know what it needs to do with the user and it will use the correct connection ticket.
Jeff Widmer
Jeff: Were you able to set the client SSL certificate correctly in ASP.NET? If Yes, then I would appreciate if you could tell me hoe it is done. I have been struggling for the last 3 weeks.
A9S6
Abhimanyu: Since I do not need the session key or require user security, I did not need to deal with a client SSL certificate. Just posting to https://apps.quickbooks.com/j/AppGateway from ASP.NET was all I needed to do.
Jeff Widmer