This sample is a C# ASP.NET web service application that communicates with QuickBooks Point of Sale via QBWebConnector. The sample focuses primarily on demonstrating how to set up all web service web methods to run against QBWebConnector and does not focus on any particular use case.

Step 1
Install QuickBooks desktop from here

Step 2

Install QuickBooks Web Connector from here

Step 3

Create a new web service in Visual Studio and give the name of this web service as QWCPOSWebService
Step 4
Open your Service class file and paste the below code into that.
  1. //
  2. // QuickBooks Web Connector Sample: WCWebService
  3. // Copyright (c) 2006-2007 Intuit, Inc
  4. //
  5. // This sample is a C# ASP.NET web service application that
  6. // communicates with QuickBooks Point of Sale via QBWebConnector. The
  7. // sample focuses primarily on demonstrating how to setup all web service
  8. // web methods to run against QBWebConnector and does not focus on any
  9. // particular use case. For simplicity, it sends three request XMLs:
  10. // CustomerQuery, ItenInventoryQuery and PurchaseOrderQuery.
  11. //
  12. // This sample assumes that you have configured IIS with ASP.NET and
  13. // have a functional system to deploy this web service sample. If you have
  14. // not yet configured ASP.NET with IIS, you may need to run the
  15. // following command from c:\windows\Microsoft.NET\Framework\
  16. // your_asp_dot_net_version path: -
  17. // aspnet_regiis /i
  18. // This will help avoid the occasional message from microsoft development
  19. // environment such as "VS.NET has detected that the specified web server
  20. // is not running ASP.NET version 1.1. You will be unable to run ASP.NET
  21. // web applications or services)".
  22. /*
  23. * Useful note about using OwnerID and FileID in a real-world application
  24. *
  25. * As part of your QB Web Connector configuration (.QWC) file, you include
  26. * OwnerID and FileID. Following note on these two parameters may be useful.
  27. *
  28. * OwnerID -- this is a GUID that represents your application or suite of
  29. * applications, if your application needs to store private data in the
  30. * company file for one reason or another (one of the most common cases
  31. * being to check if you have communicated with this company file before,
  32. * and possibly some data about that communication) that private data will
  33. * be visible to any application that knows the OwnerID.
  34. *
  35. * FileID -- this is a GUID we stamp in the file on your behalf
  36. * (using your OwnerID) as a private data extension to the "Company" object.
  37. * It allows an application to verify that the company file it is exchanging
  38. * data with is consistent over time (by doing a CompanyQuery with the field
  39. * set appropriately and reading the DataExtRet values returned.
  40. *
  41. * */
  42. using System;
  43. using System.Collections;
  44. using System.ComponentModel;
  45. using System.Data;
  46. using System.Diagnostics;
  47. using System.Web;
  48. using System.Web.Services;
  49. using System.IO;
  50. using System.Security.Cryptography;
  51. using Microsoft.Win32;
  52. using System.Xml;
  53. using System.Text.RegularExpressions;
  54. namespace QWCPOSWebService
  55. {
  56. /// <summary>
  57. /// Web Service Namespace="http://developer.intuit.com/",
  58. /// Web Service Name="QWCPOSWebService",
  59. /// Web Service Description="Sample WebService in ASP.NET to
  60. /// demonstrate QBWebConnector with QuickBooks POS
  61. /// </summary>
  62. [WebService(
  63. Namespace = "http://developer.intuit.com/",
  64. Name = "QWCPOSWebService",
  65. Description = "Sample WebService in ASP.NET to demonstrate " +
  66. "QBWebConnector with QuickBooks POS")]
  67. // Important Note:
  68. // You should keep the namespace as http://developer.intuit.com/ for all web
  69. // services that communicates with QuickBooks Web Connector.
  70. public class QWCPOSWebService : System.Web.Services.WebService
  71. {
  72. #region GlobalVariables
  73. System.Diagnostics.EventLog evLog = new System.Diagnostics.EventLog();
  74. public int count = 0;
  75. public ArrayList req = new ArrayList();
  76. #endregion
  77. #region Constructor
  78. public QWCPOSWebService()
  79. {
  80. //CODEGEN: This call is required by the ASP.NET
  81. //Web Services Designer
  82. InitializeComponent();
  83. // Initializing EventLog for logging
  84. initEvLog();
  85. }
  86. #endregion
  87. #region AutoGeneratedMethods
  88. //Required by the Web Services Designer
  89. private IContainer components = null;
  90. /// <summary>
  91. /// Required method for Designer support - do not modify
  92. /// the contents of this method with the code editor.
  93. /// </summary>
  94. private void InitializeComponent()
  95. {
  96. }
  97. /// <summary>
  98. /// Clean up any resources being used.
  99. /// </summary>
  100. protected override void Dispose(bool disposing)
  101. {
  102. if (disposing && components != null)
  103. {
  104. components.Dispose();
  105. }
  106. base.Dispose(disposing);
  107. }
  108. #endregion
  109. #region WebMethods
  110. [WebMethod]
  111. /// <summary>
  112. /// WebMethod# 1 - clientVersion()
  113. /// To enable web service with QBWC version control
  114. /// Signature: public string clientVersion(string strVersion)
  115. ///
  116. /// IN:
  117. /// string strVersion
  118. ///
  119. /// OUT:
  120. /// string errorOrWarning
  121. /// Possible values:
  122. /// string retVal
  123. /// - NULL or <emptyString> = QBWC will let the web service update
  124. /// - "E:<any text>" = popup ERROR dialog with <any text>
  125. /// - abort update and force download of new QBWC.
  126. /// - "W:<any text>" = popup WARNING dialog with <any text>
  127. /// - choice to user, continue update or not.
  128. /// </summary>
  129. public string clientVersion(string strVersion)
  130. {
  131. string evLogTxt = "WebMethod: clientVersion() has been called " +
  132. "by QBWebconnector" + "\r\n\r\n";
  133. evLogTxt = evLogTxt + "Parameters received:\r\n";
  134. evLogTxt = evLogTxt + "string strVersion = " + strVersion + "\r\n";
  135. evLogTxt = evLogTxt + "\r\n";
  136. string retVal = null;
  137. double recommendedVersion = 1.5;
  138. double supportedMinVersion = 1.0;
  139. double suppliedVersion = Convert.ToDouble(this.parseForVersion(strVersion));
  140. evLogTxt = evLogTxt + "QBWebConnector version = " + strVersion + "\r\n";
  141. evLogTxt = evLogTxt + "Recommended Version = " + recommendedVersion.ToString() + "\r\n";
  142. evLogTxt = evLogTxt + "Supported Minimum Version = " + supportedMinVersion.ToString() + "\r\n";
  143. evLogTxt = evLogTxt + "SuppliedVersion = " + suppliedVersion.ToString() + "\r\n";
  144. if (suppliedVersion < recommendedVersion)
  145. {
  146. retVal = "W:We recommend that you upgrade your QBWebConnector";
  147. }
  148. else if (suppliedVersion < supportedMinVersion)
  149. {
  150. retVal = "E:You need to upgrade your QBWebConnector";
  151. }
  152. evLogTxt = evLogTxt + "\r\n";
  153. evLogTxt = evLogTxt + "Return values: " + "\r\n";
  154. evLogTxt = evLogTxt + "string retVal = " + retVal;
  155. logEvent(evLogTxt);
  156. return retVal;
  157. }
  158. [WebMethod]
  159. /// <summary>
  160. /// WebMethod# 2 - authenticate()
  161. /// To verify username and password for the web connector that is trying to connect
  162. /// Signature: public string[] authenticate(string strUserName, string strPassword)
  163. ///
  164. /// IN:
  165. /// string strUserName
  166. /// string strPassword
  167. ///
  168. /// OUT:
  169. /// string[] authReturn
  170. /// Possible values:
  171. /// string[0] = ticket
  172. /// string[1]
  173. /// - empty string = use current company file
  174. /// - "none" = no further request/no further action required
  175. /// - "nvu" = not valid user
  176. /// - any other string value = use this company file
  177. /// </summary>
  178. public string[] authenticate(string strUserName, string strPassword)
  179. {
  180. string evLogTxt = "WebMethod: authenticate() has been called by QBWebconnector" + "\r\n\r\n";
  181. evLogTxt = evLogTxt + "Parameters received:\r\n";
  182. evLogTxt = evLogTxt + "string strUserName = " + strUserName + "\r\n";
  183. evLogTxt = evLogTxt + "string strPassword = " + strPassword + "\r\n";
  184. evLogTxt = evLogTxt + "\r\n";
  185. string[] authReturn = new string[2];
  186. // Code below uses a random GUID to use as session ticket
  187. // An example of a GUID is {85B41BEE-5CD9-427a-A61B-83964F1EB426}
  188. authReturn[0] = System.Guid.NewGuid().ToString();
  189. // For simplicity of sample, a hardcoded username/password is used.
  190. // In real world, you should handle authentication in using a standard way.
  191. // For example, you could validate the username/password against an LDAP
  192. // or a directory server
  193. string pwd = "password";
  194. evLogTxt = evLogTxt + "Password locally stored = " + pwd + "\r\n";
  195. if (strUserName.ToUpper().Trim().Equals("USERNAME") && strPassword.ToUpper().Trim().Equals(pwd.ToUpper()))
  196. {
  197. // An empty string for authReturn[1] means asking QBWebConnector
  198. // to connect to the company file that is currently openned in QB
  199. authReturn[1] = "Company Data=IqbalStore";
  200. }
  201. else
  202. {
  203. authReturn[1] = "nvu";
  204. }
  205. // You could also return "none" to indicate there is no work to do
  206. // or a company filename in the format C:\full\path\to\company.qbw
  207. // based on your program logic and requirements.
  208. evLogTxt = evLogTxt + "\r\n";
  209. evLogTxt = evLogTxt + "Return values: " + "\r\n";
  210. evLogTxt = evLogTxt + "string[] authReturn[0] = " + authReturn[0].ToString() + "\r\n";
  211. evLogTxt = evLogTxt + "string[] authReturn[1] = " + authReturn[1].ToString();
  212. logEvent(evLogTxt);
  213. return authReturn;
  214. }
  215. [WebMethod(Description = "This web method facilitates web service to handle connection errors between QuickBooks and QBWebConnector", EnableSession = true)]
  216. /// <summary>
  217. /// WebMethod# 3 - connectionError()
  218. /// To facilitate capturing of QuickBooks error and notifying it to web services
  219. /// Signature: public string connectionError (string ticket, string hresult, string message)
  220. ///
  221. /// IN:
  222. /// string ticket = A GUID based ticket string to maintain identity of QBWebConnector
  223. /// string hresult = An HRESULT value thrown by QuickBooks when trying to make connection
  224. /// string message = An error message corresponding to the HRESULT
  225. ///
  226. /// OUT:
  227. /// string retVal
  228. /// Possible values:
  229. /// - “done” = no further action required from QBWebConnector
  230. /// - any other string value = use this name for company file
  231. /// </summary>
  232. public string connectionError(string ticket, string hresult, string message)
  233. {
  234. if (Session["ce_counter"] == null)
  235. {
  236. Session["ce_counter"] = 0;
  237. }
  238. string evLogTxt = "WebMethod: connectionError() has been called by QBWebconnector" + "\r\n\r\n";
  239. evLogTxt = evLogTxt + "Parameters received:\r\n";
  240. evLogTxt = evLogTxt + "string ticket = " + ticket + "\r\n";
  241. evLogTxt = evLogTxt + "string hresult = " + hresult + "\r\n";
  242. evLogTxt = evLogTxt + "string message = " + message + "\r\n";
  243. evLogTxt = evLogTxt + "\r\n";
  244. string retVal = null;
  245. //-2147418113 = Can't connect to the database
  246. const string CANT_CONNECT_TO_DB = "0x8000FFFF";
  247. // Add more as you need...
  248. if (hresult.Trim().Equals(CANT_CONNECT_TO_DB))
  249. {
  250. evLogTxt = evLogTxt + "HRESULT = " + hresult + "\r\n";
  251. evLogTxt = evLogTxt + "Message = " + message + "\r\n";
  252. retVal = "DONE";
  253. }
  254. else
  255. {
  256. // Depending on various hresults return different value
  257. if ((int)Session["ce_counter"] == 0)
  258. {
  259. // Try again with this company file
  260. evLogTxt = evLogTxt + "HRESULT = " + hresult + "\r\n";
  261. evLogTxt = evLogTxt + "Message = " + message + "\r\n";
  262. evLogTxt = evLogTxt + "Sending connection string as \"Company Data=\" to QBWebConnector.";
  263. retVal = "Company Data=";
  264. }
  265. else
  266. {
  267. evLogTxt = evLogTxt + "HRESULT = " + hresult + "\r\n";
  268. evLogTxt = evLogTxt + "Message = " + message + "\r\n";
  269. evLogTxt = evLogTxt + "Sending DONE to stop.";
  270. retVal = "DONE";
  271. }
  272. }
  273. evLogTxt = evLogTxt + "\r\n";
  274. evLogTxt = evLogTxt + "Return values: " + "\r\n";
  275. evLogTxt = evLogTxt + "string retVal = " + retVal + "\r\n";
  276. logEvent(evLogTxt);
  277. Session["ce_counter"] = ((int)Session["ce_counter"]) + 1;
  278. return retVal;
  279. }
  280. [WebMethod(Description = "This web method facilitates web service to send request XML to QuickBooks via QBWebConnector", EnableSession = true)]
  281. /// <summary>
  282. /// WebMethod# 4 - sendRequestXML()
  283. /// Signature: public string sendRequestXML(string ticket, string strHCPResponse, string strCompanyFileName,
  284. /// string Country, int qbXMLMajorVers, int qbXMLMinorVers)
  285. ///
  286. /// IN:
  287. /// int qbXMLMajorVers
  288. /// int qbXMLMinorVers
  289. /// string ticket
  290. /// string strHCPResponse
  291. /// string strCompanyFileName
  292. /// string Country
  293. /// int qbXMLMajorVers
  294. /// int qbXMLMinorVers
  295. ///
  296. /// OUT:
  297. /// string request
  298. /// Possible values:
  299. /// - “any_string” = Request XML for QBWebConnector to process
  300. /// - "" = No more request XML
  301. /// </summary>
  302. public string sendRequestXML(string ticket, string strHCPResponse, string strCompanyFileName,
  303. string qbXMLCountry, int qbXMLMajorVers, int qbXMLMinorVers)
  304. {
  305. if (Session["counter"] == null)
  306. {
  307. Session["counter"] = 0;
  308. }
  309. string evLogTxt = "WebMethod: sendRequestXML() has been called by QBWebconnector" + "\r\n\r\n";
  310. evLogTxt = evLogTxt + "Parameters received:\r\n";
  311. evLogTxt = evLogTxt + "string ticket = " + ticket + "\r\n";
  312. evLogTxt = evLogTxt + "string strHCPResponse = " + strHCPResponse + "\r\n";
  313. evLogTxt = evLogTxt + "string strCompanyFileName = " + strCompanyFileName + "\r\n";
  314. evLogTxt = evLogTxt + "string qbXMLCountry = " + qbXMLCountry + "\r\n";
  315. evLogTxt = evLogTxt + "int qbXMLMajorVers = " + qbXMLMajorVers.ToString() + "\r\n";
  316. evLogTxt = evLogTxt + "int qbXMLMinorVers = " + qbXMLMinorVers.ToString() + "\r\n";
  317. evLogTxt = evLogTxt + "\r\n";
  318. ArrayList req = buildRequest();
  319. string request = "";
  320. int total = req.Count;
  321. count = Convert.ToInt32(Session["counter"]);
  322. if (count < total)
  323. {
  324. request = req[count].ToString();
  325. evLogTxt = evLogTxt + "sending request no = " + (count + 1) + "\r\n";
  326. Session["counter"] = ((int)Session["counter"]) + 1;
  327. }
  328. else
  329. {
  330. count = 0;
  331. Session["counter"] = 0;
  332. request = "";
  333. }
  334. evLogTxt = evLogTxt + "\r\n";
  335. evLogTxt = evLogTxt + "Return values: " + "\r\n";
  336. evLogTxt = evLogTxt + "string request = " + request + "\r\n";
  337. logEvent(evLogTxt);
  338. return request;
  339. }
  340. [WebMethod(Description = "This web method facilitates web service to receive response XML from QuickBooks via QBWebConnector", EnableSession = true)]
  341. /// <summary>
  342. /// WebMethod# 5 - receiveResponseXML()
  343. /// Signature: public int receiveResponseXML(string ticket, string response, string hresult, string message)
  344. ///
  345. /// IN:
  346. /// string ticket
  347. /// string response
  348. /// string hresult
  349. /// string message
  350. ///
  351. /// OUT:
  352. /// int retVal
  353. /// Greater than zero = There are more request to send
  354. /// 100 = Done. no more request to send
  355. /// Less than zero = Custom Error codes
  356. /// </summary>
  357. public int receiveResponseXML(string ticket, string response, string hresult, string message)
  358. {
  359. string evLogTxt = "WebMethod: receiveResponseXML() has been called by QBWebconnector" + "\r\n\r\n";
  360. evLogTxt = evLogTxt + "Parameters received:\r\n";
  361. evLogTxt = evLogTxt + "string ticket = " + ticket + "\r\n";
  362. evLogTxt = evLogTxt + "string response = " + response + "\r\n";
  363. evLogTxt = evLogTxt + "string hresult = " + hresult + "\r\n";
  364. evLogTxt = evLogTxt + "string message = " + message + "\r\n";
  365. evLogTxt = evLogTxt + "\r\n";
  366. int retVal = 0;
  367. if (!hresult.ToString().Equals(""))
  368. {
  369. // if there is an error with the response received, web service could also return a -ve int
  370. evLogTxt = evLogTxt + "HRESULT = " + hresult + "\r\n";
  371. evLogTxt = evLogTxt + "Message = " + message + "\r\n";
  372. retVal = -101;
  373. }
  374. else
  375. {
  376. evLogTxt = evLogTxt + "Length of response received = " + response.Length + "\r\n";
  377. ArrayList req = buildRequest();
  378. int total = req.Count;
  379. int count = Convert.ToInt32(Session["counter"]);
  380. int percentage = (count * 100) / total;
  381. if (percentage >= 100)
  382. {
  383. count = 0;
  384. Session["counter"] = 0;
  385. }
  386. retVal = percentage;
  387. }
  388. evLogTxt = evLogTxt + "\r\n";
  389. evLogTxt = evLogTxt + "Return values: " + "\r\n";
  390. evLogTxt = evLogTxt + "int retVal= " + retVal.ToString() + "\r\n";
  391. logEvent(evLogTxt);
  392. return retVal;
  393. }
  394. [WebMethod]
  395. /// <summary>
  396. /// WebMethod# 6 - getLastError()
  397. /// Signature: public string getLastError(string ticket)
  398. ///
  399. /// IN:
  400. /// string ticket
  401. ///
  402. /// OUT:
  403. /// string retVal
  404. /// Possible Values:
  405. /// Error message describing last web service error
  406. /// </summary>
  407. public string getLastError(string ticket)
  408. {
  409. string evLogTxt = "WebMethod: getLastError() has been called by QBWebconnector" + "\r\n\r\n";
  410. evLogTxt = evLogTxt + "Parameters received:\r\n";
  411. evLogTxt = evLogTxt + "string ticket = " + ticket + "\r\n";
  412. evLogTxt = evLogTxt + "\r\n";
  413. int errorCode = 0;
  414. string retVal = null;
  415. if (errorCode == -101)
  416. {
  417. retVal = "QuickBooks was not running!"; // This is just an example of custom user errors
  418. }
  419. else
  420. {
  421. retVal = "Error!";
  422. }
  423. evLogTxt = evLogTxt + "\r\n";
  424. evLogTxt = evLogTxt + "Return values: " + "\r\n";
  425. evLogTxt = evLogTxt + "string retVal= " + retVal + "\r\n";
  426. logEvent(evLogTxt);
  427. return retVal;
  428. }
  429. [WebMethod]
  430. /// <summary>
  431. /// WebMethod# 7 - closeConnection()
  432. /// At the end of a successful update session, QBWebConnector will call this web method.
  433. /// Signature: public string closeConnection(string ticket)
  434. ///
  435. /// IN:
  436. /// string ticket
  437. ///
  438. /// OUT:
  439. /// string closeConnection result
  440. /// </summary>
  441. public string closeConnection(string ticket)
  442. {
  443. string evLogTxt = "WebMethod: closeConnection() has been called by QBWebconnector" + "\r\n\r\n";
  444. evLogTxt = evLogTxt + "Parameters received:\r\n";
  445. evLogTxt = evLogTxt + "string ticket = " + ticket + "\r\n";
  446. evLogTxt = evLogTxt + "\r\n";
  447. string retVal = null;
  448. retVal = "OK";
  449. evLogTxt = evLogTxt + "\r\n";
  450. evLogTxt = evLogTxt + "Return values: " + "\r\n";
  451. evLogTxt = evLogTxt + "string retVal= " + retVal + "\r\n";
  452. logEvent(evLogTxt);
  453. return retVal;
  454. }
  455. #endregion
  456. #region UtilityMethods
  457. private void initEvLog()
  458. {
  459. try
  460. {
  461. string source = "WCWebService";
  462. if (!System.Diagnostics.EventLog.SourceExists(source))
  463. System.Diagnostics.EventLog.CreateEventSource(source, "Application");
  464. evLog.Source = source;
  465. }
  466. catch { };
  467. return;
  468. }
  469. private void logEvent(string logText)
  470. {
  471. try
  472. {
  473. evLog.WriteEntry(logText);
  474. }
  475. catch { };
  476. return;
  477. }
  478. public ArrayList buildRequest()
  479. {
  480. string strRequestXML = "";
  481. XmlDocument inputXMLDoc = null;
  482. // CustomerQuery
  483. inputXMLDoc = new XmlDocument();
  484. inputXMLDoc.AppendChild(inputXMLDoc.CreateXmlDeclaration("1.0", null, null));
  485. inputXMLDoc.AppendChild(inputXMLDoc.CreateProcessingInstruction("qbposxml", "version=\"1.0\""));
  486. XmlElement qbposXML = inputXMLDoc.CreateElement("QBPOSXML");
  487. inputXMLDoc.AppendChild(qbposXML);
  488. XmlElement qbposXMLMsgsRq = inputXMLDoc.CreateElement("QBPOSXMLMsgsRq");
  489. qbposXML.AppendChild(qbposXMLMsgsRq);
  490. qbposXMLMsgsRq.SetAttribute("onError", "stopOnError");
  491. XmlElement customerQueryRq = inputXMLDoc.CreateElement("CustomerQueryRq");
  492. qbposXMLMsgsRq.AppendChild(customerQueryRq);
  493. customerQueryRq.SetAttribute("requestID", "1");
  494. XmlElement maxReturned = inputXMLDoc.CreateElement("MaxReturned");
  495. customerQueryRq.AppendChild(maxReturned).InnerText = "1";
  496. strRequestXML = inputXMLDoc.OuterXml;
  497. req.Add(strRequestXML);
  498. // Clean up
  499. strRequestXML = "";
  500. inputXMLDoc = null;
  501. qbposXML = null;
  502. qbposXMLMsgsRq = null;
  503. maxReturned = null;
  504. // ItemInventoryQuery
  505. inputXMLDoc = new XmlDocument();
  506. inputXMLDoc.AppendChild(inputXMLDoc.CreateXmlDeclaration("1.0", null, null));
  507. inputXMLDoc.AppendChild(inputXMLDoc.CreateProcessingInstruction("qbposxml", "version=\"1.0\""));
  508. qbposXML = inputXMLDoc.CreateElement("QBPOSXML");
  509. inputXMLDoc.AppendChild(qbposXML);
  510. qbposXMLMsgsRq = inputXMLDoc.CreateElement("QBPOSXMLMsgsRq");
  511. qbposXML.AppendChild(qbposXMLMsgsRq);
  512. qbposXMLMsgsRq.SetAttribute("onError", "stopOnError");
  513. XmlElement itemInventoryQueryRq = inputXMLDoc.CreateElement("ItemInventoryQueryRq");
  514. qbposXMLMsgsRq.AppendChild(itemInventoryQueryRq);
  515. itemInventoryQueryRq.SetAttribute("requestID", "2");
  516. maxReturned = inputXMLDoc.CreateElement("MaxReturned");
  517. itemInventoryQueryRq.AppendChild(maxReturned).InnerText = "1";
  518. strRequestXML = inputXMLDoc.OuterXml;
  519. req.Add(strRequestXML);
  520. // Clean up
  521. strRequestXML = "";
  522. inputXMLDoc = null;
  523. qbposXML = null;
  524. qbposXMLMsgsRq = null;
  525. maxReturned = null;
  526. // PurchaseOrderQuery
  527. inputXMLDoc = new XmlDocument();
  528. inputXMLDoc.AppendChild(inputXMLDoc.CreateXmlDeclaration("1.0", null, null));
  529. inputXMLDoc.AppendChild(inputXMLDoc.CreateProcessingInstruction("qbposxml", "version=\"1.0\""));
  530. qbposXML = inputXMLDoc.CreateElement("QBPOSXML");
  531. inputXMLDoc.AppendChild(qbposXML);
  532. qbposXMLMsgsRq = inputXMLDoc.CreateElement("QBPOSXMLMsgsRq");
  533. qbposXML.AppendChild(qbposXMLMsgsRq);
  534. qbposXMLMsgsRq.SetAttribute("onError", "stopOnError");
  535. XmlElement purchaseOrderQueryRq = inputXMLDoc.CreateElement("PurchaseOrderQueryRq");
  536. qbposXMLMsgsRq.AppendChild(purchaseOrderQueryRq);
  537. purchaseOrderQueryRq.SetAttribute("requestID", "3");
  538. maxReturned = inputXMLDoc.CreateElement("MaxReturned");
  539. purchaseOrderQueryRq.AppendChild(maxReturned).InnerText = "1";
  540. strRequestXML = inputXMLDoc.OuterXml;
  541. req.Add(strRequestXML);
  542. // InvoiceQuery
  543. //inputXMLDoc = new XmlDocument();
  544. //inputXMLDoc.AppendChild(inputXMLDoc.CreateXmlDeclaration("1.0",null, null));
  545. // inputXMLDoc.AppendChild(inputXMLDoc.CreateProcessingInstruction("qbxml", "version=\"4.0\""));
  546. // qbXML = inputXMLDoc.CreateElement("QBXML");
  547. // inputXMLDoc.AppendChild(qbXML);
  548. // qbXMLMsgsRq = inputXMLDoc.CreateElement("QBXMLMsgsRq");
  549. // qbXML.AppendChild(qbXMLMsgsRq);
  550. // qbXMLMsgsRq.SetAttribute("onError", "stopOnError");
  551. // XmlElement invoiceQueryRq = inputXMLDoc.CreateElement("InvoiceQueryRq");
  552. //qbXMLMsgsRq.AppendChild(invoiceQueryRq);
  553. // invoiceQueryRq.SetAttribute("requestID", "2");
  554. // maxReturned=inputXMLDoc.CreateElement("MaxReturned");
  555. // invoiceQueryRq.AppendChild(maxReturned).InnerText="1";
  556. // strRequestXML = inputXMLDoc.OuterXml;
  557. // req.Add(strRequestXML);
  558. return req;
  559. }
  560. private string parseForVersion(string input)
  561. {
  562. // This method is created just to parse the first two version components
  563. // out of the standard four component version number:
  564. // <Major>.<Minor>.<Release>.<Build>
  565. //
  566. // As long as you get the version in right format, you could use
  567. // any algorithm here.
  568. string retVal = "";
  569. string major = "";
  570. string minor = "";
  571. Regex version = new Regex(@"^(?\d+)\.(?\d+)(\.\w+){0,2}$", RegexOptions.Compiled);
  572. Match versionMatch = version.Match(input);
  573. if (versionMatch.Success)
  574. {
  575. major = versionMatch.Result("${major}");
  576. minor = versionMatch.Result("${minor}");
  577. retVal = major + "." + minor;
  578. }
  579. else
  580. {
  581. retVal = input;
  582. }
  583. return retVal;
  584. }
  585. #endregion
  586. }
  587. }

Step 5

Now, create the QuickBooks file for making the connection between QuickBooks desktop and your web service.

As part of your QB Web Connector configuration (.QWC) file, you include OwnerID and FileID. The following note on these two parameters may be useful.

OwnerID

This is a GUID that represents your application or suite of applications if your application needs to store private data in the company file. Another reason (one of the most common cases being to check if you have communicated with this company file before, and possibly some data about that communication) is that private data will be visible to any application that knows the OwnerID.

FileID

This is a GUID we stamp in the file on your behalf (using your OwnerID) as a private data extension to the "Company" object. It allows an application to verify that the company file it is exchanging data with is consistent over time (by doing a Company Query with the field).

An example of GUID is {85B41BEE-5CD9-427a-A61B-83964F1EB426}

Given below is the code for them.QWC file.

  1. <?xml version="1.0"?><QBWCXML>
  2. <AppName>hanavision</AppName>
  3. <AppID>1</AppID>
  4. <AppURL>http://localhost:50528/QWCPOSWebService.asmx</AppURL>
  5. <AppDescription>A short description for QWCPOSWebService</AppDescription>
  6. <AppSupport>http://localhost:50528/QWCPOSWebService.asmx?wsdl</AppSupport>
  7. <OwnerID>{87EDAAF8-0000-1111-2222-4BA79C2F8998}</OwnerID>
  8. <FileID>{CA1C3EB8-0000-1111-2222-8D5B438B83AC}</FileID>
  9. <UserName>Bhavdip</UserName>
  10. <QBType>QBFS</QBType>
  11. <Style>Document</Style>
  12. <AuthFlags>0xF</AuthFlags>
  13. </QBWCXML>

Note
Don’t forget to change the localhost path.

Step 6

Now, open your web connector and add this file into your web connector. After successfully adding this, now add your file to a web connector.
How To Integrate Quickbook Desktop Using Web Service (QBXMl)
  1. Add your file using the "Add an Application" button; then choose your QBC file.

  2. Add password which is similar to the one in your code of web services.

  3. Select this web service in web connector using the checkbox.

  4. Click the "Update selected" button for running your code of web service.

If you want to run like scheduler, then you can set autorun and give the timing in every Min text box. So now, your QuickBooks desktop and your web service are connected using this web connector.

Authorizing the Application

On the first time that an application connects to a QuickBooks company file, QuickBooks should be opened and a user must be there to authorize the access. When we try to save a customer again and QuickBooks is running this time, a dialog will appear in QuickBooks, as shown in the figure below. We should take note that this will block the current thread so if we used the UI thread, then the UI will become unresponsive.

How To Integrate Quickbook Desktop Using Web Service (QBXMl)
Example qbXML Request to "Add Customer".
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <?qbxml version="2.0"?>
  3. <QBXML>
  4. <QBXMLMsgsRq onError="stopOnError">
  5. <CustomerAddRq requestID="15">
  6. <CustomerAdd>
  7. <Name>20706 - Eastern XYZ University</Name>
  8. <CompanyName>Eastern XYZ University</CompanyName>
  9. <FirstName>Keith</FirstName>
  10. <LastName>Palmer</LastName>
  11. <BillAddress>
  12. <Addr1>Eastern XYZ University</Addr1>
  13. <Addr2>College of Engineering</Addr2>
  14. <Addr3>123 XYZ Road</Addr3>
  15. <City>Storrs-Mansfield</City>
  16. <State>CT</State>
  17. <PostalCode>06268</PostalCode>
  18. <Country>United States</Country>
  19. </BillAddress>
  20. <Phone>860-634-1602</Phone>
  21. <AltPhone>860-429-0021</AltPhone>
  22. <Fax>860-429-5183</Fax>
  23. <Email>[email protected]</Email>
  24. <Contact>Keith Palmer</Contact>
  25. </CustomerAdd>
  26. </CustomerAddRq>
  27. </QBXMLMsgsRq>
  28. </QBXML>

Example qbXML Response to "Add Customer".

  1. <?xml version="1.0" ?>
  2. <QBXML>
  3. <QBXMLMsgsRs>
  4. <CustomerAddRs requestID="15" statusCode="0" statusSeverity="Info" statusMessage="Status OK">
  5. <CustomerRet>
  6. <ListID>F540000-1197683154</ListID>
  7. <TimeCreated>2007-12-14T20:45:54-05:00</TimeCreated>
  8. <TimeModified>2007-12-14T20:45:54-05:00</TimeModified>
  9. <EditSequence>1197683154</EditSequence>
  10. <Name>20706 - Eastern XYZ University</Name>
  11. <FullName>20706 - Eastern XYZ University</FullName>
  12. <IsActive>true</IsActive>
  13. <Sublevel>0</Sublevel>
  14. <CompanyName>Eastern XYZ University</CompanyName>
  15. <FirstName>Keith</FirstName>
  16. <LastName>Palmer</LastName>
  17. <BillAddress>
  18. <Addr1>Eastern XYZ University</Addr1>
  19. <Addr2>College of Engineering</Addr2>
  20. <Addr3>123 XYZ Road</Addr3>
  21. <City>Storrs-Mansfield</City>
  22. <State>CT</State>
  23. <PostalCode>88130</PostalCode>
  24. <Country>USA</Country>
  25. </BillAddress>
  26. <Phone>860-634-1602</Phone>
  27. <AltPhone>860-429-0021</AltPhone>
  28. <Fax>860-429-5183</Fax>
  29. <Email>[email protected]</Email>
  30. <Contact>Keith Palmer</Contact>
  31. <Balance>0.00</Balance>
  32. <TotalBalance>0.00</TotalBalance>
  33. <JobStatus>None</JobStatus>
  34. </CustomerRet>
  35. </CustomerAddRs>
  36. </QBXMLMsgsRs>
  37. </QBXML>

Example qbXML to "Add an Invoice".

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <?qbxml version="2.0"?>
  3. <QBXML>
  4. <QBXMLMsgsRq onError="stopOnError">
  5. <InvoiceAddRq requestID="2">
  6. <InvoiceAdd>
  7. <CustomerRef>
  8. <ListID>F560000-1197683156</ListID> <!-- or
  9. <Name>Bhavdip</Name> -->
  10. </CustomerRef>
  11. <TxnDate>2007-12-14</TxnDate>
  12. <RefNumber>9668</RefNumber>
  13. <BillAddress>
  14. <Addr1>56 Cowles Road</Addr1>
  15. <City>Willington</City>
  16. <State>CT</State>
  17. <PostalCode>06279</PostalCode>
  18. <Country>United States</Country>
  19. </BillAddress>
  20. <PONumber></PONumber>
  21. <Memo></Memo>
  22. <InvoiceLineAdd>
  23. <ItemRef>
  24. <FullName>Downloaded Invoice</FullName>
  25. </ItemRef>
  26. <Desc>Item 1 Description Goes Here</Desc>
  27. <Quantity>1</Quantity>
  28. <Rate>295</Rate>
  29. </InvoiceLineAdd>
  30. <InvoiceLineAdd>
  31. <ItemRef>
  32. <FullName>Downloaded Invoice</FullName>
  33. </ItemRef>
  34. <Desc>Item 2 Description Goes Here</Desc>
  35. <Quantity>3</Quantity>
  36. <Rate>25</Rate>
  37. </InvoiceLineAdd>
  38. </InvoiceAdd>
  39. </InvoiceAddRq>
  40. </QBXMLMsgsRq>
  41. </QBXML>
Note
Make sure of the Ref like below,
  1. <CustomerRef>
  2. <ListID>F560000-1197683156</ListID> <!-- or
  3. <Name>Bhavdip</Name> -->
  4. </CustomerRef>

If your customer "Bhavdip" is already added in your QuickBooks desktop, then your invoice will be added. Otherwise, it will return an error.

Thus, first add a customer, item etc. which is required for the invoice. Then and only then make an invoice.