我们正在尝试测试联合包裹服务(UPS)“昆腾”接口测试获取订单状态信息。我们得到了跟踪号API,但是遇到了QVEvents问题。
UPS“出站订阅帐户”已设置,有效并链接到我的帐号。用户访问在“用户设置”屏幕中选中“昆腾视图数据”视图。我很幸运地得到了跟踪API使用类似的代码,所以认为我可以排除用户名或密码问题。这两个API有什么不同的操作吗? (例如:SSL要求,HTTP标头设置?)
以下是跟踪API的代码(“Tack by Waybill”),它对我有用:
<?php
// UPS Tracker API - track specfic Waybill
// DEV server
$access = '99999999399999999';
$userid = '9999999';
$passwd = '999999999999';
$endpointUrl = 'https://www.ups.com/ups.app/xml/Track';
$outFileName = './XOLTResult.xml';
// Note: you need at least a UPS DEV account to test this
$data ="<?xml version=\"1.0\"?><AccessRequest xml:lang='en-US'>
<AccessLicenseNumber>$access</AccessLicenseNumber>
<UserId>$userid</UserId>
<Password>$passwd</Password>
</AccessRequest>
<?xml version=\"1.0\"?>
<TrackRequest>
<Request>
<TransactionReference>
<CustomerContext>
<InternalKey>hello</InternalKey>
</CustomerContext>
<XpciVersion>1.0</XpciVersion>
</TransactionReference>
<RequestAction>Track</RequestAction>
</Request>
<TrackingNumber>9999999999999999</TrackingNumber>
</TrackRequest>";
$ch = curl_init("https://www.ups.com/ups.app/xml/Track");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_TIMEOUT, 60);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch,CURLOPT_POSTFIELDS,$data);
$result=curl_exec ($ch);
$data = strstr($result, '<?');
$xml=simplexml_load_string($data);
echo "<pre>";
print_r($xml);
以下是提供错误消息的Quantum API代码......
<?php
// UPS Quantum API ("Show list of recent tracking information")
// DEV server
$access = '99999999399999999';
$userid = '9999999';
$passwd = '999999999999';
$endpointUrl = 'https://wwwcie.ups.com/ups.app/xml/QVEvents'; // URL for testing Quantum
$outFileName = './XOLTResult.xml';
try
{
$data ="<?xml version=\"1.0\"?>
<AccessRequest xml:lang=\"en-US\">
<AccessLicenseNumber>$access</AccessLicenseNumber>
<UserId>$userid</UserId>
<Password>$passwd</Password>
</AccessRequest>
<?xml version=\"1.0\"?>
<QuantumViewRequest xml:lang=\"en-US\">
<Request>
<TransactionReference>
<CustomerContext>Test XML</CustomerContext>
<XpciVersion>1.0007</XpciVersion>
</TransactionReference>
<RequestAction>QVEvents</RequestAction>
<IntegrationIndicator></IntegrationIndicator>
</Request>
</QuantumViewRequest>";
$postData = array
(
'content' => $data
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_URL,$endpointUrl);
curl_setopt($ch, CURLOPT_VERBOSE, 1 );
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/x-www-form-urlencoded'));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // disable SSL verification if not installed
//curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSLVERSION, 3); // use Secure Socket v3 SSL3
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'SSLv3');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$postData);
if( ! $result = curl_exec($ch))
{
trigger_error(curl_error($ch));
}
echo $result;
$data = strstr($result, '<?');
$xml=simplexml_load_string($data);
echo "<pre>";
print_r($xml);
}
catch(Exception $ex)
{
echo ($ex . "!");
}
curl_close($ch);
这是实际发送给UPS的XML ... [注意双xml标头是他们要求的,它适用于所有其他API,所以不要怪我]
<?xml version="1.0"?>
<AccessRequest xml:lang="en-US">
<AccessLicenseNumber>999</AccessLicenseNumber>
<UserId>999</UserId>
<Password>999</Password>
</AccessRequest>
<?xml version="1.0"?>
<QuantumViewRequest xml:lang="en-US">
<Request>
<TransactionReference>
<CustomerContext>Test XML</CustomerContext>
<XpciVersion>1.0007</XpciVersion>
</TransactionReference>
<RequestAction>QVEvents</RequestAction>
<IntegrationIndicator></IntegrationIndicator>
</Request>
</QuantumViewRequest>
错误消息如下所示:
HTTP/1.1 100 Continue
HTTP/1.1 200 OK
Date: Fri, 25 Jul 2014 22:50:57 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: application/xml
<QuantumViewResponse><Response><TransactionReference><XpciVersion>1.0</XpciVersion>
</TransactionReference><ResponseStatusCode>0</ResponseStatusCode>
<ResponseStatusDescription>Failure</ResponseStatusDescription><Error>
<ErrorSeverity>Hard</ErrorSeverity><ErrorCode>10001</ErrorCode>
<ErrorDescription>The XML document is not well formed</ErrorDescription></Error>
</Response></QuantumViewResponse><pre>
我没有使用UPS SCA_SDO库,因为它不会安装在我的电脑上。也许我应该再看一遍,但我的程序员向我保证这不是必要的,与此问题无关。双重堆叠的XML看起来很可疑,但手动说这是UPS想要的方式。我想UPS会根据请求运行预处理器。
答案 0 :(得分:1)
根据2014年7月的量子视图Developers Guide,未使用IntegrationIndicator
。
从Request
节点删除它,它应该按预期运行:
<Request>
<TransactionReference>
<CustomerContext>Test XML</CustomerContext>
<XpciVersion>1.0007</XpciVersion>
</TransactionReference>
<RequestAction>QVEvents</RequestAction>
</Request>
答案 1 :(得分:1)
我对特定的UPS Api不熟悉,但错误消息提示不是well-formed XML document:
错误代码10001: XML文档格式不正确
根据Quantum View Package - XML Developers Guide,您在HTTP请求中使用了错误的后期数据编码和内容类型,这会破坏XML,使其不再格式化。这会导致错误代码10001.
相反,使用正确的内容类型的HTTP请求正文(您正在使用 multipart/form-data
这是错误的,正确的内容类型是 {{1}使用您对UPS XML API端点的HTTP POST请求并对XML数据进行编码也是正确的,您应该使用XML库来创建XML(不是您的具体问题,但是当您知道XML是正确的,并且创建不会像在字符串连接中那样容易出错,这有助于排除相同错误代码的大量错误情况。)
要修复代码中错误内容类型的具体问题,请替换以下行:
application/x-www-form-urlencoded
与
$postData = array
(
'content' => $data
);
这可确保curl库将“$postData = $data;
”用作 Content-Type 而不是“application/x-www-form-urlencoded
”。然后,您会收到许可证号无效的正确错误消息:
错误代码250003:无效的访问许可证号
作为替代方案,这是另一个小例子,展示了如何使用标准PHP HTTP包装器和用于XML处理的SimpleXML库以及使用DOMDocument的响应的更好输出:
multipart/form-data
此示例使用您在示例中提供的数据,而不是代码10001(代码生成的数据),它提供了有关数据样本中真实已知错误的更精确的错误信息:
错误代码250003:无效的访问许可证号
/*
* UPS API XML PHP Example (Open Source)
*/
# Every UPS XML API request needs an AccessRequest XML payload first
$accessRequest = new SimpleXMLElement("<AccessRequest xml:lang='en-US'/>");
$accessRequest->AccessLicenseNumber = '99999999399999999';
$accessRequest->UserId = '9999999';
$accessRequest->Password = '999999999999';
# Exemplary testing QuantumViewRequest
$url = 'https://wwwcie.ups.com/ups.app/xml/QVEvents';
$request = new SimpleXMLElement('<QuantumViewRequest xml:lang="en-US"/>');
# UPS XML API requires two concatenated XML documents send via a HTTP POST
# request with a HTTP request body and the content-type set to
# application/x-www-form-urlencoded
$options = array(
'http' => array(
'header' => "Content-type: application/x-www-form-urlencoded",
'method' => 'POST',
'content' => $accessRequest->asXML() . $request->asXML(),
),
);
$context = stream_context_create($options);
$result = file_get_contents($url, false, $context);
# output the response nicely formatted
$dom = new DOMDocument();
$dom->loadXML($result);
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
echo $dom->saveXML();
我确信这是正确的错误信息。
为了简洁示例,我已将<?xml version="1.0"?>
<QuantumViewResponse>
<Response>
<TransactionReference/>
<ResponseStatusCode>0</ResponseStatusCode>
<ResponseStatusDescription>Failure</ResponseStatusDescription>
<Error>
<ErrorSeverity>Hard</ErrorSeverity>
<ErrorCode>250003</ErrorCode>
<ErrorDescription>Invalid Access License number</ErrorDescription>
</Error>
</Response>
</QuantumViewResponse>
和file_get_contents
的错误处理权移除。
答案 2 :(得分:0)
IntegrationIndicator已被弃用。也不要将数据作为数组传递。