8

My QBWC app has been working fine but I got notified this morning by accounting that it had suddenly stopped working. Specifically it was failing to authenticate. I checked the QWCLog.txt and found this

20130510.14:25:19 UTC : QBWebConnector.SOAPWebService.do_authenticate() : QBWC1012: Authentication failed due to following error message. SOAP-ERROR: Parsing WSDL: Couldn't load from 'http://developer.intuit.com/uploadedFiles/Support/QBWebConnectorSvc.wsdl' : failed to load external entity "http://developer.intuit.com/uploadedFiles/Support/QBWebConnectorSvc.wsdl"

That's a new one (and I have extended error logging on so I can see full calls). So I went to the WSDL file and find... it's 404?!

I even tried one of my AWS instances to make sure it's not just me

wget http://developer.intuit.com/uploadedFiles/Support/QBWebConnectorSvc.wsdl --2013-05-10 15:10:50-- http://developer.intuit.com/uploadedFiles/Support/QBWebConnectorSvc.wsdl Resolving developer.intuit.com (developer.intuit.com)... 206.108.40.170 Connecting to developer.intuit.com (developer.intuit.com)|206.108.40.170|:80... connected. HTTP request sent, awaiting response... 404 Not Found 2013-05-10 15:10:51 ERROR 404: Not Found.

Anyone else getting this? Is there a new URL I don't know about? I just need to get this working again.

Chris Moschini
  • 36,764
  • 19
  • 160
  • 190
Machavity
  • 30,841
  • 27
  • 92
  • 100
  • There was a site update last night and it looks like this was missed. I will see what can be done. – William Lorfing May 10 '13 at 16:29
  • 1
    This file has not changed in a couple of years, so you really don't need to pull it every time. You should be able to use the last version. – William Lorfing May 10 '13 at 17:16
  • I wasn't really trying to pull it every time (and the local server does cache it). The sample code I found used it that way and it's been running like that for well over a year. I found a copy on Github so I pulled that into my local codebase and that works for now. Still, a lot of people point to that URL for the WSDL so you might want to consider putting it back or add a 301 to a new location. The copy I found is here: https://github.com/consolibyte/quickbooks-php/blob/master/QuickBooks/QBWebConnectorSvc.wsdl – Machavity May 10 '13 at 18:54
  • 5
    @WilliamLorfing If Intuit can restore this file, they should - the default behavior for almost every SOAP library out there is to pull the WSDL down from the net and cache it for a few hours, before reaching out and pulling it again. It's likely going to break *a lot* of people's stuff if the file disappears. – Keith Palmer Jr. May 10 '13 at 19:03
  • @KeithPalmer-consolibyte That's true but oddly doesn't apply here. The WSDL in this case is for you to implement the server-side portion of, so you're locking in a bunch of code that implements the WSDL just the once. The client-side that would normally fetch the WSDL to check if it's changed, and then talk to the server, is Quickbooks Web Connector, which doesn't behave like a typical web services client and frankly doesn't care what if any WSDL is stored anywhere. – Chris Moschini Jan 25 '15 at 18:27
  • Life gets worse from here. The WSDL missing is just one part of the failure of Quickbooks WC documentation: https://developer-static.intuit.com/qbSDK-current/doc/PDF/QBWC_proguide.pdf I've put together a list of issues here: http://goo.gl/rC6r65 If someone has the answer to any of these, comment here, happy to ask them as separate questions so you can get deserved karma. – Chris Moschini Jan 25 '15 at 18:50

2 Answers2

13

The link to the QBWC WSDL within the QuickBooks Web Connector Programmer’s Guide is still returning a 404. This post on the Intuit support board indicates you can download a (presumably) up to date version of the WSDL here.

Brane
  • 3,257
  • 2
  • 42
  • 53
JohnB
  • 1,231
  • 1
  • 18
  • 33
4

I agree that this problem currently exists.

This helped me: Old Code:
$server = new SoapServer($wsdl_url);
New Code:
$server = new SoapServer('file:///home/to/wsdl/file');

And this is the what I have in my wsdl file:

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://developer.intuit.com/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" targetNamespace="http://developer.intuit.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <wsdl:types>
    <s:schema elementFormDefault="qualified" targetNamespace="http://developer.intuit.com/">
      <s:element name="authenticate">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="strUserName" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="strPassword" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="authenticateResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="authenticateResult" type="tns:ArrayOfString" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:complexType name="ArrayOfString">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string" />
        </s:sequence>
      </s:complexType>

<!-- added these two methods -->
    <s:element name="serverVersion">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="strVersion" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="serverVersionResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="serverVersionResult" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="clientVersion">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="strVersion" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="clientVersionResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="clientVersionResult" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>


      <s:element name="sendRequestXML">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="ticket" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="strHCPResponse" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="strCompanyFileName" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="qbXMLCountry" type="s:string" />
            <s:element minOccurs="1" maxOccurs="1" name="qbXMLMajorVers" type="s:int" />
            <s:element minOccurs="1" maxOccurs="1" name="qbXMLMinorVers" type="s:int" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="sendRequestXMLResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="sendRequestXMLResult" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="receiveResponseXML">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="ticket" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="response" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="hresult" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="message" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="receiveResponseXMLResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="1" maxOccurs="1" name="receiveResponseXMLResult" type="s:int" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="connectionError">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="ticket" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="hresult" type="s:string" />
            <s:element minOccurs="0" maxOccurs="1" name="message" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="connectionErrorResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="connectionErrorResult" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="getLastError">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="ticket" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="getLastErrorResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="getLastErrorResult" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="closeConnection">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="ticket" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
      <s:element name="closeConnectionResponse">
        <s:complexType>
          <s:sequence>
            <s:element minOccurs="0" maxOccurs="1" name="closeConnectionResult" type="s:string" />
          </s:sequence>
        </s:complexType>
      </s:element>
    </s:schema>
  </wsdl:types>

  <wsdl:message name="authenticateSoapIn">
    <wsdl:part name="parameters" element="tns:authenticate" />
  </wsdl:message>
  <wsdl:message name="authenticateSoapOut">
    <wsdl:part name="parameters" element="tns:authenticateResponse" />
  </wsdl:message>

<!-- added this part -->
  <wsdl:message name="serverVersionSoapIn">
    <wsdl:part name="parameters" element="tns:serverVersion" />
  </wsdl:message>
  <wsdl:message name="serverVersionSoapOut">
    <wsdl:part name="parameters" element="tns:serverVersionResponse" />
  </wsdl:message>
  <wsdl:message name="clientVersionSoapIn">
    <wsdl:part name="parameters" element="tns:clientVersion" />
  </wsdl:message>
  <wsdl:message name="clientVersionSoapOut">
    <wsdl:part name="parameters" element="tns:clientVersionResponse" />
  </wsdl:message>


  <wsdl:message name="sendRequestXMLSoapIn">
    <wsdl:part name="parameters" element="tns:sendRequestXML" />
  </wsdl:message>
  <wsdl:message name="sendRequestXMLSoapOut">
    <wsdl:part name="parameters" element="tns:sendRequestXMLResponse" />
  </wsdl:message>
  <wsdl:message name="receiveResponseXMLSoapIn">
    <wsdl:part name="parameters" element="tns:receiveResponseXML" />
  </wsdl:message>
  <wsdl:message name="receiveResponseXMLSoapOut">
    <wsdl:part name="parameters" element="tns:receiveResponseXMLResponse" />
  </wsdl:message>
  <wsdl:message name="connectionErrorSoapIn">
    <wsdl:part name="parameters" element="tns:connectionError" />
  </wsdl:message>
  <wsdl:message name="connectionErrorSoapOut">
    <wsdl:part name="parameters" element="tns:connectionErrorResponse" />
  </wsdl:message>
  <wsdl:message name="getLastErrorSoapIn">
    <wsdl:part name="parameters" element="tns:getLastError" />
  </wsdl:message>
  <wsdl:message name="getLastErrorSoapOut">
    <wsdl:part name="parameters" element="tns:getLastErrorResponse" />
  </wsdl:message>
  <wsdl:message name="closeConnectionSoapIn">
    <wsdl:part name="parameters" element="tns:closeConnection" />
  </wsdl:message>
  <wsdl:message name="closeConnectionSoapOut">
    <wsdl:part name="parameters" element="tns:closeConnectionResponse" />
  </wsdl:message>
  <wsdl:portType name="QBWebConnectorSvcSoap">

    <!-- add this chunk -->
    <wsdl:operation name="serverVersion">
      <wsdl:input message="tns:serverVersionSoapIn" />
      <wsdl:output message="tns:serverVersionSoapOut" />
    </wsdl:operation>
    <wsdl:operation name="clientVersion">
      <wsdl:input message="tns:clientVersionSoapIn" />
      <wsdl:output message="tns:clientVersionSoapOut" />
    </wsdl:operation>


    <wsdl:operation name="authenticate">
      <wsdl:input message="tns:authenticateSoapIn" />
      <wsdl:output message="tns:authenticateSoapOut" />
    </wsdl:operation>
    <wsdl:operation name="sendRequestXML">
      <wsdl:input message="tns:sendRequestXMLSoapIn" />
      <wsdl:output message="tns:sendRequestXMLSoapOut" />
    </wsdl:operation>
    <wsdl:operation name="receiveResponseXML">
      <wsdl:input message="tns:receiveResponseXMLSoapIn" />
      <wsdl:output message="tns:receiveResponseXMLSoapOut" />
    </wsdl:operation>
    <wsdl:operation name="connectionError">
      <wsdl:input message="tns:connectionErrorSoapIn" />
      <wsdl:output message="tns:connectionErrorSoapOut" />
    </wsdl:operation>
    <wsdl:operation name="getLastError">
      <wsdl:input message="tns:getLastErrorSoapIn" />
      <wsdl:output message="tns:getLastErrorSoapOut" />
    </wsdl:operation>
    <wsdl:operation name="closeConnection">
      <wsdl:input message="tns:closeConnectionSoapIn" />
      <wsdl:output message="tns:closeConnectionSoapOut" />
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="QBWebConnectorSvcSoap" type="tns:QBWebConnectorSvcSoap">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
    <!-- this too was added... -->
    <wsdl:operation name="serverVersion">
      <soap:operation soapAction="http://developer.intuit.com/serverVersion" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="clientVersion">
      <soap:operation soapAction="http://developer.intuit.com/clientVersion" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>

    <wsdl:operation name="authenticate">
      <soap:operation soapAction="http://developer.intuit.com/authenticate" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="sendRequestXML">
      <soap:operation soapAction="http://developer.intuit.com/sendRequestXML" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="receiveResponseXML">
      <soap:operation soapAction="http://developer.intuit.com/receiveResponseXML" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="connectionError">
      <soap:operation soapAction="http://developer.intuit.com/connectionError" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="getLastError">
      <soap:operation soapAction="http://developer.intuit.com/getLastError" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
    <wsdl:operation name="closeConnection">
      <soap:operation soapAction="http://developer.intuit.com/closeConnection" style="document" />
      <wsdl:input>
        <soap:body use="literal" />
      </wsdl:input>
      <wsdl:output>
        <soap:body use="literal" />
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="QBWebConnectorSvc">
    <wsdl:port name="QBWebConnectorSvcSoap" binding="tns:QBWebConnectorSvcSoap">
      <soap:address location="https://idn.vogelfam.net/QBMSDonorSample/QBWebConnectorSvc.asmx" />
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
TheDuke
  • 214
  • 2
  • 3
  • You actually don't even need the file:// declaration. I passed the full path in and it worked fine. – Machavity May 10 '13 at 20:07
  • Didn't work for me without the file:// declaration. Might be something with VirtualBox, or maybe the cms I am using (drupal). – TheDuke May 10 '13 at 21:03