PHP SOAP版本不匹配(错误版本)

时间:2016-02-10 10:22:39

标签: php web-services soap wsdl

我正在为我们的系统实施皇家邮政。我想使用他们的API,但我没有运气。我仍然收到错误:

[faultstring] => Wrong Version [faultcode] => VersionMismatch [faultcodens] => http://schemas.xmlsoap.org/soap/envelope/ 

我已经尝试过SOAP 1.2版,但我确信他们使用的是SOAP 1.1。这是WSDL:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="TrackingAPIService" targetNamespace="http://www.royalmailgroup.com/api/track/V1" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://www.royalmailgroup.com/api/track/V1" xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<wsdl:documentation>Version 1.1.1</wsdl:documentation>
<wsdl:types>
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.royalmailgroup.com/WSDLapi/track/V1" xmlns:tns="http://www.royalmailgroup.com/WSDLapi/track/V1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:import namespace="http://www.royalmailgroup.com/api/track/V1" schemaLocation="Tracking_API_V1_1_1.xsd"/>
    </xs:schema>
</wsdl:types>
<wsdl:message name="getSingleItemHistoryRequest">
    <wsdl:part element="tns:getSingleItemHistoryRequest" name="parameters"/>
</wsdl:message>
<wsdl:message name="getSingleItemHistoryResponse">
    <wsdl:part element="tns:getSingleItemHistoryResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="getProofOfDeliveryRequest">
    <wsdl:part element="tns:getProofOfDeliveryRequest" name="parameters"/>
</wsdl:message>
<wsdl:message name="getProofOfDeliveryResponse">
    <wsdl:part element="tns:getProofOfDeliveryResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="getMultiItemSummaryRequest">
    <wsdl:part element="tns:getMultiItemSummaryRequest" name="parameters"/>
</wsdl:message>
<wsdl:message name="getMultiItemSummaryResponse">
    <wsdl:part element="tns:getMultiItemSummaryResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="getSingleItemSummaryRequest">
    <wsdl:part element="tns:getSingleItemSummaryRequest" name="parameters"/>
</wsdl:message>
<wsdl:message name="getSingleItemSummaryResponse">
    <wsdl:part element="tns:getSingleItemSummaryResponse" name="parameters"/>
</wsdl:message>
<wsdl:message name="faultResponse">
    <wsdl:part element="tns:exceptionDetails" name="parameters"/>
</wsdl:message>
<wsdl:portType name="TrackingAPIServicePortType">
    <wsdl:operation name="getSingleItemHistory">
        <wsdl:documentation>Provides a history of tracks for a single mail item.</wsdl:documentation>
        <wsdl:input message="tns:getSingleItemHistoryRequest" wsaw:Action="urn:getSingleItemHistoryRequest"/>
        <wsdl:output message="tns:getSingleItemHistoryResponse" wsaw:Action="urn:getSingleItemHistoryResponse"/>
        <wsdl:fault message="tns:faultResponse" name="faultResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getProofOfDelivery">
        <wsdl:documentation>Provides the details captured at the point of delivery as proof that delivery has occurred. Note that a proof of delivery is only captured by the delivery track for those service offerings that require a signature on delivery. Please also note that for data protection reasons the API does not currently supply the signature image captured at the point of delivery.</wsdl:documentation>
        <wsdl:input message="tns:getProofOfDeliveryRequest" wsaw:Action="urn:getProofOfDeliveryRequest"/>
        <wsdl:output message="tns:getProofOfDeliveryResponse" wsaw:Action="urn:getProofOfDeliveryResponse"/>
        <wsdl:fault message="tns:faultResponse" name="faultResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getMultiItemSummary">
        <wsdl:input message="tns:getMultiItemSummaryRequest" wsaw:Action="urn:getMultiItemSummaryRequest"/>
        <wsdl:output message="tns:getMultiItemSummaryResponse" wsaw:Action="urn:getMultiItemSummaryResponse"/>
        <wsdl:fault message="tns:faultResponse" name="faultResponse"/>
    </wsdl:operation>
    <wsdl:operation name="getSingleItemSummary">
        <wsdl:documentation>Provides the latest track for a mail item.</wsdl:documentation>
        <wsdl:input message="tns:getSingleItemSummaryRequest" wsaw:Action="urn:getSingleItemSummaryRequest"/>
        <wsdl:output message="tns:getSingleItemSummaryResponse" wsaw:Action="urn:getSingleItemSummaryResponse"/>
        <wsdl:fault message="tns:faultResponse" name="faultResponse"/>
    </wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TrackingAPIServiceSoap11Binding" type="tns:TrackingAPIServicePortType">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getSingleItemHistory">
        <soap:operation soapAction="urn:getSingleItemHistory" style="document"/>
        <wsdl:input>
            <soap:body use="literal"/>
        </wsdl:input>
        <wsdl:output>
            <soap:body use="literal"/>
        </wsdl:output>
        <wsdl:fault name="faultResponse">
            <soap:fault name="faultResponse" use="literal"/>
        </wsdl:fault>
    </wsdl:operation>
    <wsdl:operation name="getProofOfDelivery">
        <soap:operation soapAction="urn:getProofOfDelivery" style="document"/>
        <wsdl:input>
            <soap:body use="literal"/>
        </wsdl:input>
        <wsdl:output>
            <soap:body use="literal"/>
        </wsdl:output>
        <wsdl:fault name="faultResponse">
            <soap:fault name="faultResponse" use="literal"/>
        </wsdl:fault>
    </wsdl:operation>
    <wsdl:operation name="getMultiItemSummary">
        <soap:operation soapAction="urn:getMultiItemSummary" style="document"/>
        <wsdl:input>
            <soap:body use="literal"/>
        </wsdl:input>
        <wsdl:output>
            <soap:body use="literal"/>
        </wsdl:output>
        <wsdl:fault name="faultResponse">
            <soap:fault name="faultResponse" use="literal"/>
        </wsdl:fault>
    </wsdl:operation>
    <wsdl:operation name="getSingleItemSummary">
        <soap:operation soapAction="urn:getSingleItemSummary" style="document"/>
        <wsdl:input>
            <soap:body use="literal"/>
        </wsdl:input>
        <wsdl:output>
            <soap:body use="literal"/>
        </wsdl:output>
        <wsdl:fault name="faultResponse">
            <soap:fault name="faultResponse" use="literal"/>
        </wsdl:fault>
    </wsdl:operation>
</wsdl:binding>
<wsdl:service name="TrackingAPIService">
    <wsdl:port binding="tns:TrackingAPIServiceSoap11Binding" name="TrackingAPIServiceHttpSoap11Endpoint">
        <soap:address location="https://api.royalmail.net/tracking"/>
    </wsdl:port>
</wsdl:service>

这是我的PHP代码:

private static function generateIntegrationHeader($type){
    $version = '1.0';
    if ($type === 'Shipping') {
        $version = '2';
    } elseif ($type === 'Tracking') {
        $version = '1';
    }

    return [
        'identification' => [
            'applicationId' => self::APPLICATION_ID,
            'transactionId' => mt_rand(10000000, 100000000)
        ]
    ];
}

public static function status($trackingCode) {
    $mode = array (
        'soap_version' => 'SOAP_1_1',  // use soap 1.1 client
        'trace' => true,
        'exceptions' => true
    );
    try {
        $client = new SoapClient(BASE_DIR.'/tridy/wsdl/ukroyal/Tracking_API_V1_1_1.wsdl', $mode);
        $client->__setLocation(self::ENDPOINT_URL_TRACK_PRODUCTION);
        $resp = $client->__soapCall('getSingleItemHistory', [self::generateSingleItemHistoryRequest($trackingCode)]);
        if($resp->trackdetail->header == "Delivered") {
            return ['status' => parcel::STATUS_DELIVERED];
        }
        return ['status' => parcel::STATUS_EN_ROUTE];
    }
    catch(SoapFault $ex) {
        //echo htmlentities($client->__getLastRequest());
        //echo htmlentities($client->__getLastRequestHeaders());
        print_r($ex);
    }
}

这是我发送的请求:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://www.royalmailgroup.com/integration/core/V1"
xmlns:ns2="http://www.royalmailgroup.com/api/track/V1">
<SOAP-ENV:Body>
    <ns2:getSingleItemHistoryRequest>
        <ns2:integrationHeader>
            <ns1:identification>
                <ns1:applicationId>CENSORED</ns1:applicationId>
                <ns1:transactionId>20704393</ns1:transactionId>
            </ns1:identification>
        </ns2:integrationHeader>
        <ns2:trackingNumber>RQ221150275GB</ns2:trackingNumber>
    </ns2:getSingleItemHistoryRequest>
</SOAP-ENV:Body>

有什么不对?

感谢您的时间。

2 个答案:

答案 0 :(得分:2)

我的OpenCart扩展程序的买家遇到了同样的问题。奇怪的是,他们与其他多个用户使用的OpenCart版本相同,包括我的演示网站。经过大量(和大量)挖掘后,我将问题缩小到5.3.11中修复的PHP错误。

以下是该错误的详细信息:https://bugs.php.net/bug.php?id=49853

基本上,http头的stream_context部分被忽略,并且包含客户端ID和秘密。

包含在内是一种解决方法:

ini_set('user_agent', 'PHP-SOAP/' . PHP_VERSION . "\r\n" . $str_auth_header);

由此,我创建了以下修复程序:

if ((!defined('PHP_VERSION_ID')) || (PHP_VERSION_ID < 50311)) {
    ini_set('user_agent', 'PHP-SOAP/' . PHP_VERSION . "\r\n" .
        implode(
            "\r\n",
            array(
                'Accept: application/soap+xml',
                'X-IBM-Client-Id: ' . $this->client_id,
                'X-IBM-Client-Secret: ' . $this->client_secret,
            )
        )
    );
}
在我设置stream_context选项之前添加的

。这取自this answer上的PHP and Royal Mail Tracking API

虽然看起来您还没有设置stream_context(因为$mode只有soap_versiontraceexceptions),但希望PHP版本bug解释了&#34; VersionMismatch&#34; /&#34;错误的版本&#34;错误。

答案 1 :(得分:0)

在我的代码中我使用了这样的旧版本:

$result = $this->serve()->__soapCall($functionName, $arguments);

protected function serve()

{

if (is_null($this->client))
{
    $this->client = new SoapClient($this->wsdl, $this->options);
}
return $this->client;

}

然后当我改为这个时,解决这个问题:

$sms_client = new SoapClient($this->wsdl, array('encoding'=>'UTF-8'));

    $result =  $sms_client->$functionName($arguments);