问题
so my issue is according to the documentation (wich is pretty slim and not the greatest) the xml i have is everything that is required, but im getting this error code back
<?xml version="1.0" encoding="UTF-8"?>
<Error><Number>80040B19</Number><Description>XML Syntax Error: Please check the XML request to see if it can be parsed.</Description><Source>USPSCOM::DoAuth</Source></Error>
this doesnt make much sense to me because my account is in production mode, and as i said according to the documentation i have everything that is required, i have spent the last 2 days trying to get this to work and nothing.
the VerifyAddress function works fine, but the RateCheck function does not work.
class USPS
{
protected $Endpoint = 'http://production.shippingapis.com/ShippingAPI.dll';
protected $SecureEndpoint = 'https://secure.shippingapis.com/ShippingAPI.dll';
protected $TestEndpoint = 'http://stg-production.shippingapis.com/ShippingAPI.dll';
protected $TestSecureEndpoint = 'https://stg-secure.shippingapis.com/ShippingAPI.dll';
private $username = 'example’;
function VerifyAddress($address1, $address2, $city, $state, $zip)
{
$xml = '<AddressValidateRequest%20USERID="'.$this->username.'">
<Address>
<Address1>'.$address1.'</Address1>
<Address2>'.$address2.'</Address2>
<City>'.$city.'</City>
<State>'.$state.'</State>
<Zip5>'.$zip.'</Zip5>
<Zip4></Zip4>
</Address>
</AddressValidateRequest>';
//build the data
$data = $this->AddressVerify . $xml;
//send for the request
$verified = $this->Request($data);
//return he results
return $verified;
}
function RateCheck($packages, $zipDest, $service='PRIORITY', $zipOrigin='93274', $pounds='3', $ounces='0',
$container='RECTANGULAR', $size='LARGE', $width='13', $length='14', $height='6', $girth='38')
{
$packageIDS = array('1ST'=>1, '2ND'=>2, '3RD'=>3, '4TH'=>4, '5TH'=>5, '6TH'=>6, '7TH'=>7, '8th'=>8,'9TH'=>9,
'10th'=>10);
$packagexml = array();
for($i=1;$i<=$packages;$i++)
{
$PackageID = array_search($i, $packageIDS);
$packagexml[] = '<Package ID="'.$PackageID.'">
<Service>'.$service.'</Service>
<ZipOrigination>'.$zipOrigin.'</ZipOrigination>
<ZipDestination>'.$zipDest.'</ZipDestination>
<Pounds>'.$pounds.'/Pounds>
<Ounces>'.$ounces.'</Ounces>
<Container>'.$container.'</Container>
<Size>'.$size.'</Size>
<Width>'.$width.'</Width>
<Length>'.$length.'</Length>
<Height>'.$height.'</Height>
<Girth>'.$girth.'</Girth>
</Package>';
}
$xml2 = '';
foreach($packagexml as $package)
{
$xml2 .= $package;
}
$data = 'API=RateV4&XML=<RateV4Request USERID="'.$this->username.'"><Revision>2</Revision>'.$xml2.'</RateV4Request>';
$RateResult = $this->Request($data);
return $RateResult;
}
function Request($data)
{
$ch = curl_init();
// set the target url
curl_setopt($ch, CURLOPT_URL,$this->Endpoint);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// parameters to post
curl_setopt($ch, CURLOPT_POST, 1);
// send the POST values to usps
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
//curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$result=curl_exec ($ch);
curl_close($ch);
$Parseresult = $this->parseResult($result);
return $Parseresult;
}
function parseResult($responce)
{
$data = strstr($responce, '<?');
echo '<!-- '. $data. ' -->'; // Uncomment to show XML in comments
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $data, $vals, $index);
xml_parser_free($xml_parser);
$params = array();
$level = array();
foreach ($vals as $xml_elem) {
if ($xml_elem['type'] == 'open') {
if (array_key_exists('attributes',$xml_elem)) {
list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
} else {
$level[$xml_elem['level']] = $xml_elem['tag'];
}
}
if ($xml_elem['type'] == 'complete') {
$start_level = 1;
$php_stmt = '$params';
while($start_level < $xml_elem['level']) {
$php_stmt .= '[$level['.$start_level.']]';
$start_level++;
}
$php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
eval($php_stmt);
}
}
return $params;
}
}
回答1:
The reason I was getting this was because I had unescaped ampersands in my XML that I was posting to the USPS API. Before you POST the XML, print the XML out on your screen just to see exactly what is being posted. I'm not sure how to do this in php (maybe echo?) but in python I would do print(my_xml_string)
.
Like I said, my generated xml had ampersand characters in it &
, I fixed the problem by replacing those with &
. Again, I'm not way familiar with php but python would be my_xml_string.replace('&', '&')
. This is because an ampersand in XML needs to be 'closed' with a ;
.
来源:https://stackoverflow.com/questions/31164890/usps-api-returning-80040b19-error-code-and-account-is-in-production