问题
I am just trying to understand the QBWC authenticate process. I am trying to build a real basic SOAP Server in PHP that just authenticates the QBWC requests.
Here's my WSDL:
<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://developer.intuit.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://developer.intuit.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">WebService for QBFS created using ASP.NET to troubleshoot QuickBooks WebConnector</wsdl:documentation>
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://developer.intuit.com/">
<s:element name="serverVersion">
<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="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>
<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="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="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="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="authenticateSoapIn">
<wsdl:part name="parameters" element="tns:authenticate" />
</wsdl:message>
<wsdl:message name="authenticateSoapOut">
<wsdl:part name="parameters" element="tns:authenticateResponse" />
</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="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="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="TroubleshootWebServiceFSSoap">
<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="connectionError">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">This web method facilitates web service to handle connection error between QBWC and QB</wsdl:documentation>
<wsdl:input message="tns:connectionErrorSoapIn" />
<wsdl:output message="tns:connectionErrorSoapOut" />
</wsdl:operation>
<wsdl:operation name="sendRequestXML">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">This web method facilitates web service to send request XML to QuickBooks via QBWebConnector</wsdl:documentation>
<wsdl:input message="tns:sendRequestXMLSoapIn" />
<wsdl:output message="tns:sendRequestXMLSoapOut" />
</wsdl:operation>
<wsdl:operation name="receiveResponseXML">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">This web method facilitates web service to receive response XML from QuickBooks via QBWebConnector</wsdl:documentation>
<wsdl:input message="tns:receiveResponseXMLSoapIn" />
<wsdl:output message="tns:receiveResponseXMLSoapOut" />
</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="TroubleshootWebServiceFSSoap" type="tns:TroubleshootWebServiceFSSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<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="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="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="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:binding name="TroubleshootWebServiceFSSoap12" type="tns:TroubleshootWebServiceFSSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="serverVersion">
<soap12:operation soapAction="http://developer.intuit.com/serverVersion" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="clientVersion">
<soap12:operation soapAction="http://developer.intuit.com/clientVersion" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="authenticate">
<soap12:operation soapAction="http://developer.intuit.com/authenticate" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="connectionError">
<soap12:operation soapAction="http://developer.intuit.com/connectionError" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="sendRequestXML">
<soap12:operation soapAction="http://developer.intuit.com/sendRequestXML" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="receiveResponseXML">
<soap12:operation soapAction="http://developer.intuit.com/receiveResponseXML" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="getLastError">
<soap12:operation soapAction="http://developer.intuit.com/getLastError" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="closeConnection">
<soap12:operation soapAction="http://developer.intuit.com/closeConnection" style="document" />
<wsdl:input>
<soap12:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap12:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TroubleshootWebServiceFS">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">WebService for QBFS created using ASP.NET to troubleshoot QuickBooks WebConnector</wsdl:documentation>
<wsdl:port name="TroubleshootWebServiceFSSoap" binding="tns:TroubleshootWebServiceFSSoap">
<soap:address location="https://test.developer.intuit.com/QBWC/TroubleshootWebServiceFS/Service.asmx" />
</wsdl:port>
<wsdl:port name="TroubleshootWebServiceFSSoap12" binding="tns:TroubleshootWebServiceFSSoap12">
<soap12:address location="https://test.developer.intuit.com/QBWC/TroubleshootWebServiceFS/Service.asmx" />
</wsdl:port>
</wsdl:service>
Here is the real basic code I am using on the PHP Server side:
ini_set( 'soap.wsdl_cache_enabled', '0' );
function authenticate(){
$obj = array(
'432541432412341234',
'none',
);
return $obj;
}
$server = new SoapServer('qb.wsdl');
$server->addFunction("authenticate");
$server->handle();
I realize this does not actually check the username/password but right now I am just trying to get it to work hardcoding the response.
Here is the error I see in the QBWC log:
20140328.06:11:13 UTC : QBWebConnector.SOAPWebService.do_authenticate() : QBWC1012: Authentication failed due to following error message.
Object reference not set to an instance of an object.
More info:
StackTrace = at QBWebConnector.WebService.do_authenticate(String& ticket, String& companyFileName)
Source = QBWebConnector
I am very new to writing SOAP so I could be completely missing something. I just want to understand the process better with this test.
Any help would be great.
Thanks
回答1:
Our experience has been that you actually have to create an object, and return that. e.g.:
class QuickBooks_WebConnector_Result_Authenticate
{
public $authenticateResult;
public function __construct($ticket)
{
$this->authenticateResult = array($ticket, 'none');
}
}
...
function authenticate($object)
{
return new QuickBooks_WebConnector_Result_Authenticate($ticket);
}
With that said - you might want to look into solutions that already exists to solve this issue. Implementation of the Web Connector protocol is not trivial (especially if you're not already familiar with SOAP), and this has been done before:
- https://github.com/consolibyte/quickbooks-php
That's an open-source Web Connector library that handles all of this SOAP stuff for you. There's a quick-start guide here:
- http://www.consolibyte.com/docs/index.php/PHP_DevKit_for_QuickBooks_-_Quick-Start
If you do decide to go it on your own, this provides helpful SOAP requests/responses you can use for debugging/comparing your own responses to:
- http://wiki.consolibyte.com/wiki/doku.php/quickbooks_web_connector
来源:https://stackoverflow.com/questions/22705695/quickbooks-web-connector-authenticate-with-php-soap-server