Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

USPS API returning 80040B19 error code and Account is in Production

Tags:

php

curl

usps

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;
        }
    }
like image 464
Msquared86 Avatar asked Jul 01 '15 14:07

Msquared86


2 Answers

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 &amp;. Again, I'm not way familiar with php but python would be my_xml_string.replace('&', '&amp;'). This is because an ampersand in XML needs to be 'closed' with a ;.

like image 87
teewuane Avatar answered Oct 24 '22 01:10

teewuane


soultion form Viable works .. by adding the following code in appropriate format

'.$pounds.'

i have demonstrated at usps tracking site and its now works well

like image 24
Nik Avatar answered Oct 23 '22 23:10

Nik