Jump to content

TpEnEpETE

Members
  • Content count

    3
  • Joined

  • Last visited

1 Follower

Profile Information

  • Real Name
    Milen

Recent Profile Visitors

1,137 profile views
  1. TpEnEpETE

    FedEx - Web Services v9

    Bryant, it seems like you're missing a <ns1:RequestedPackageLineItems> section in your request. Posting below is a PHP CURL implementation of a getRates request. Just replace along the tags with your corresponding info. $rq = '<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://fedex.com/ws/rate/v9"><SOAP-ENV:Body>'; $rq .= '<ns1:RateRequest>'; $rq .= '<ns1:WebAuthenticationDetail>'; $rq .= '<ns1:UserCredential>'; $rq .= '<ns1:Key>'.$this->fedex_key.'</ns1:Key>'; $rq .= '<ns1:Password>'.$this->fedex_pwd.'</ns1:Password>'; $rq .= '</ns1:UserCredential>'; $rq .= '</ns1:WebAuthenticationDetail>'; $rq .= '<ns1:ClientDetail>'; $rq .= '<ns1:AccountNumber>'.$this->fedex_act_num.'</ns1:AccountNumber>'; $rq .= '<ns1:MeterNumber>'.$this->fedex_meter_num.'</ns1:MeterNumber>'; $rq .= '</ns1:ClientDetail>'; $rq .= '<ns1:TransactionDetail>'; $rq .= '<ns1:CustomerTransactionId> *** Rate Request v9 using PHP ***</ns1:CustomerTransactionId>'; $rq .= '</ns1:TransactionDetail>'; $rq .= '<ns1:Version>'; $rq .= '<ns1:ServiceId>crs</ns1:ServiceId>'; $rq .= '<ns1:Major>9</ns1:Major>'; $rq .= '<ns1:Intermediate>0</ns1:Intermediate>'; $rq .= '<ns1:Minor>0</ns1:Minor>'; $rq .= '</ns1:Version>'; $rq .= '<ns1:ReturnTransitAndCommit>true</ns1:ReturnTransitAndCommit>'; $rq .= '<ns1:RequestedShipment>'; $rq .= '<ns1:ShipTimestamp>'.date('Y-m-d\TH:i:s'.substr(date('O'), 0, 3).':'.substr(date('O'), 3)).'</ns1:ShipTimestamp>'; $rq .= '<ns1:DropoffType>'.$this->_setDropOff().'</ns1:DropoffType>'; $rq .= '<ns1:PackagingType>YOUR_PACKAGING</ns1:PackagingType>'; $rq .= '<ns1:TotalInsuredValue>'; $rq .= '<ns1:Currency>USD</ns1:Currency>'; $rq .= '</ns1:TotalInsuredValue>'; $rq .= '<ns1:Shipper>'; $rq .= '<ns1:Address>'; $rq .= '<ns1:StreetLines>'.MODULE_SHIPPING_FEDEX_WEB_SERVICES_ADDRESS_1.'</ns1:StreetLines>'; $rq .= '<ns1:StreetLines>'.MODULE_SHIPPING_FEDEX_WEB_SERVICES_ADDRESS_2.'</ns1:StreetLines>'; $rq .= '<ns1:City>'.MODULE_SHIPPING_FEDEX_WEB_SERVICES_CITY.'</ns1:City>'; $rq .= '<ns1:StateOrProvinceCode>'.MODULE_SHIPPING_FEDEX_WEB_SERVICES_STATE.'</ns1:StateOrProvinceCode>'; $rq .= '<ns1:PostalCode>'.MODULE_SHIPPING_FEDEX_WEB_SERVICES_POSTAL.'</ns1:PostalCode>'; $rq .= '<ns1:CountryCode>'.$this->country.'</ns1:CountryCode>'; $rq .= '</ns1:Address>'; $rq .= '</ns1:Shipper>'; $rq .= '<ns1:Recipient>'; $rq .= '<ns1:Address>'; $rq .= '<ns1:StreetLines/>'; $rq .= '<ns1:StreetLines/>'; $rq .= '<ns1:PostalCode>'.$pc.'</ns1:PostalCode>'; $rq .= '<ns1:CountryCode>US</ns1:CountryCode>'; $rq .= '<ns1:Residential>true</ns1:Residential>'; $rq .= '</ns1:Address>'; $rq .= '</ns1:Recipient>'; $rq .= '<ns1:ShippingChargesPayment>'; $rq .= '<ns1:PaymentType>SENDER</ns1:PaymentType>'; $rq .= '<ns1:Payor>'; $rq .= '<ns1:AccountNumber>'.$this->fedex_act_num.'</ns1:AccountNumber>'; $rq .= '<ns1:CountryCode>'.$this->country.'</ns1:CountryCode>'; $rq .= '</ns1:Payor>'; $rq .= '</ns1:ShippingChargesPayment>'; $rq .= '<ns1:RateRequestTypes>LIST</ns1:RateRequestTypes>'; $rq .= '<ns1:PackageCount>'.$shipping_num_boxes.'</ns1:PackageCount>'; $rq .= '<ns1:PackageDetail>INDIVIDUAL_PACKAGES</ns1:PackageDetail>'; for ($i=0; $i<$shipping_num_boxes; $i++) { $rq .= '<ns1:RequestedPackageLineItems>'; $rq .= '<ns1:Weight>'; $rq .= '<ns1:Units>'.MODULE_SHIPPING_FEDEX_WEB_SERVICES_WEIGHT.'</ns1:Units>'; $rq .= '<ns1:Value>'.$shipping_weight.'</ns1:Value>'; $rq .= '</ns1:Weight>'; $rq .= '</ns1:RequestedPackageLineItems>'; } $rq .= '</ns1:RequestedShipment>'; $rq .= '</ns1:RateRequest>'; $rq .= '</SOAP-ENV:Body></SOAP-ENV:Envelope>'; $curl = curl_init(); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_USERAGENT, "PHP-SOAP/5.3.9"); curl_setopt($curl, CURLOPT_HTTPHEADER, array('Connection: Keep-Alive', 'Content-Type: text/xml; charset=utf-8', 'SOAPAction: "getRates"', 'Content-Length: '.strlen($rq) )); curl_setopt($curl, CURLOPT_POSTFIELDS, $rq); curl_setopt($curl, CURLOPT_URL, "https://gateway.fedex.com/web-services/"); $response = curl_exec($curl); curl_close($curl); $response = str_replace('<v9:', '<', $response); $response = str_replace('</v9:', '</', $response); $response = str_replace('<env:', '<', $response); $response = str_replace('</env:', '</', $response); $response = str_replace('<soapenv:', '<', $response); $response = str_replace('</soapenv:', '</', $response); $sxml = new simplexml; $resp1 = $sxml->xml_load_string($response); $response = $resp1->Body->RateReply; As you've probably already noticed the lack of support for soap will pose a couple of problems - providing alternative request mechanism and a lack of soap response parser. My solution to the second problem is a couple of str_replace calls on the response and a simplexml implementation for php4 (which by default lacks an xml_load_string function which I added to have the class looking like so: if(!class_exists('simplexml')) { class simplexml { var $result = array(); var $ignore_level = 0; var $skip_empty_values = false; var $php_errormsg; var $evalCode=""; function curl_get_file_contents($URL) { if(ini_get('allow_url_fopen') != 1) { @ini_set('allow_url_fopen', '1'); } if(ini_get('allow_url_fopen') != 1) { $c = curl_init(); curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); curl_setopt($c, CURLOPT_URL, $URL); $contents = curl_exec($c); curl_close($c); }else{ $contents = file_get_contents($URL); } if ($contents) return $contents; else return FALSE; } /** * Adds Items to Array * * @[member='param'] int $level * @[member='param'] array $tags * @[member='param'] $value * @[member='param'] string $type */ function array_insert($level, $tags, $value, $type) { $temp = ''; for ($c = $this->ignore_level + 1; $c < $level + 1; $c++) { if (isset($tags[$c]) && (is_numeric(trim($tags[$c])) || trim($tags[$c]))) { if (is_numeric($tags[$c])) { $temp .= '[' . $tags[$c] . ']'; } else { $temp .= '["' . $tags[$c] . '"]'; } } } //Fix for getting PHP variable like string in XML node values (Contributor:Saulius Okunevicius) $this->evalCode .= '$this->result' . $temp . "= '" . addslashes($value) . "';//(" . $type . ")\n"; #echo $code. "\n"; } /** * Define the repeated tags in XML file so we can set an index * * @[member='param'] array $array * @[member='Return'] array */ function xml_tags($array) { $repeats_temp = array(); $repeats_count = array(); $repeats = array(); if (is_array($array)) { $n = count($array) - 1; for ($i = 0; $i < $n; $i++) { $idn = $array[$i]['tag'].$array[$i]['level']; if(in_array($idn,$repeats_temp)){ $repeats_count[array_search($idn,$repeats_temp)]+=1; }else{ array_push($repeats_temp,$idn); $repeats_count[array_search($idn,$repeats_temp)]=1; } } } $n = count($repeats_count); for($i=0;$i<$n;$i++){ if($repeats_count[$i]>1){ array_push($repeats,$repeats_temp[$i]); } } unset($repeats_temp); unset($repeats_count); return array_unique($repeats); } /** * Converts Array Variable to Object Variable * * @[member='param'] array $arg_array * @[member='Return'] $tmp */ function array2object ($arg_array) { if (is_array($arg_array)) { $keys = array_keys($arg_array); if(!is_numeric($keys[0])) $tmp = new SimpleXMLObject; foreach ($keys as $key) { if (is_numeric($key)) $has_number = true; if (is_string($key)) $has_string = true; } if (isset($has_number) and !isset($has_string)) { foreach ($arg_array as $key => $value) { $tmp[] = $this->array2object($value); } } elseif (isset($has_string)) { foreach ($arg_array as $key => $value) { if (is_string($key)) $tmp->$key = $this->array2object($value); } } } elseif (is_object($arg_array)) { foreach ($arg_array as $key => $value) { if (is_array($value) or is_object($value)) $tmp->$key = $this->array2object($value); else $tmp->$key = $value; } } else { $tmp = $arg_array; } return $tmp; //return the object } /** * Reindexes the whole array with ascending numbers * * @[member='param'] array $array * @[member='Return'] array */ function array_reindex($array) { if (is_array($array)) { if(count($array) == 1 && array_key_exists(0, $array)){ return $this->array_reindex($array[0]); }else{ foreach($array as $keys => $items) { if (is_array($items)) { if (is_numeric($keys)) { $array[$keys] = $this->array_reindex($items); } else { $array[$keys] = $this->array_reindex(array_merge(array(), $items)); } } } } } return $array; } /** * Parse the XML generation to array object * * @[member='param'] array $array * @[member='Return'] array */ function xml_reorganize($array) { $count = count($array); $repeat = $this->xml_tags($array); $repeatedone = false; $tags = array(); $k = 0; for ($i = 0; $i < $count; $i++) { switch ($array[$i]['type']) { case 'open': array_push($tags, $array[$i]['tag']); if ($i > 0 && ($array[$i]['tag'] == $array[$i-1]['tag']) && ($array[$i-1]['type'] == 'close')) $k++; if (isset($array[$i]['value']) && ($array[$i]['value'] || !$this->skip_empty_values)) { array_push($tags, '@content'); $this->array_insert(count($tags), $tags, $array[$i]['value'], "open"); array_pop($tags); } if (in_array($array[$i]['tag'] . $array[$i]['level'], $repeat)) { if (($repeatedone == $array[$i]['tag'] . $array[$i]['level']) && ($repeatedone)) { array_push($tags, strval($k++)); } else { $repeatedone = $array[$i]['tag'] . $array[$i]['level']; array_push($tags, strval($k)); } } if (isset($array[$i]['attributes']) && $array[$i]['attributes'] && $array[$i]['level'] != $this->ignore_level) { array_push($tags, '@attributes'); foreach ($array[$i]['attributes'] as $attrkey => $attr) { array_push($tags, $attrkey); $this->array_insert(count($tags), $tags, $attr, "open"); array_pop($tags); } array_pop($tags); } break; case 'close': array_pop($tags); if (in_array($array[$i]['tag'] . $array[$i]['level'], $repeat)) { if ($repeatedone == $array[$i]['tag'] . $array[$i]['level']) { array_pop($tags); } else { $repeatedone = $array[$i + 1]['tag'] . $array[$i + 1]['level']; array_pop($tags); } } break; case 'complete': array_push($tags, $array[$i]['tag']); if (in_array($array[$i]['tag'] . $array[$i]['level'], $repeat)) { if ($repeatedone == $array[$i]['tag'] . $array[$i]['level'] && $repeatedone) { array_push($tags, strval($k)); } else { $repeatedone = $array[$i]['tag'] . $array[$i]['level']; array_push($tags, strval($k)); } } if (isset($array[$i]['value']) && ($array[$i]['value'] || !$this->skip_empty_values)) { if (isset($array[$i]['attributes']) && $array[$i]['attributes']) { array_push($tags, '@content'); $this->array_insert(count($tags), $tags, $array[$i]['value'], "complete"); array_pop($tags); } else { $this->array_insert(count($tags), $tags, $array[$i]['value'], "complete"); } } if (isset($array[$i]['attributes']) && $array[$i]['attributes']) { array_push($tags, '@attributes'); foreach ($array[$i]['attributes'] as $attrkey => $attr) { array_push($tags, $attrkey); $this->array_insert(count($tags), $tags, $attr, "complete"); array_pop($tags); } array_pop($tags); } if (in_array($array[$i]['tag'] . $array[$i]['level'], $repeat)) { array_pop($tags); $k++; } array_pop($tags); break; } } eval($this->evalCode); $last = $this->array_reindex($this->result); return $last; } /** * Get the XML contents and parse like SimpleXML * * @[member='param'] string $file * @[member='param'] string $resulttype * @[member='param'] string $encoding * @[member='Return'] array/object */ function xml_load_file($file, $resulttype = 'object', $encoding = 'UTF-8') { $php_errormsg=""; $this->result=""; $this->evalCode=""; $values=""; $data = $this->curl_get_file_contents($file); if (!$data){ return 'Cannot open xml document: ' . (isset($php_errormsg) ? $php_errormsg : $file); } $parser = xml_parser_create($encoding); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); $ok = xml_parse_into_struct($parser, $data, $values); if (!$ok) { $errmsg = sprintf("XML parse error %d '%s' at line %d, column %d (byte index %d)", xml_get_error_code($parser), xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser), xml_get_current_column_number($parser), xml_get_current_byte_index($parser)); } xml_parser_free($parser); if (!$ok) return $errmsg; if ($resulttype == 'array') return $this->xml_reorganize($values); // default $resulttype is 'object' return $this->array2object($this->xml_reorganize($values)); } function xml_load_string($string, $resulttype = 'object', $encoding = 'UTF-8') { $php_errormsg=""; $this->result=""; $this->evalCode=""; $values=""; $data = $string; if (!$data){ return 'Cannot open xml document: ' . (isset($php_errormsg) ? $php_errormsg : $file); } $parser = xml_parser_create($encoding); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1); $ok = xml_parse_into_struct($parser, $data, $values); if (!$ok) { $errmsg = sprintf("XML parse error %d '%s' at line %d, column %d (byte index %d)", xml_get_error_code($parser), xml_error_string(xml_get_error_code($parser)), xml_get_current_line_number($parser), xml_get_current_column_number($parser), xml_get_current_byte_index($parser)); } xml_parser_free($parser); if (!$ok) return $errmsg; if ($resulttype == 'array') return $this->xml_reorganize($values); // default $resulttype is 'object' return $this->array2object($this->xml_reorganize($values)); } } }
  2. TpEnEpETE

    FedEx - Web Services v9

    I contacted the FedEx support staff. They said they got only one request from us and we already sent like 20. What is the POST field name for the request XML data? I'll try and send a couple of plain POST requests via an HTTP program to see if the requests make it through to their server. Also in the WSDL file I got the last couple of lines saying: <service name="RateService"> <port name="RateServicePort" binding="ns:RateServiceSoapBinding"> <s1:address location="https://gateway.fedex.com/web-services/"/> </port> </service> Is that the URL all the POST requests go to? Cause the fedex support guy sent us a slightly different one: https://gateway.fedex.com:443/web-services (has the port number) I ran the soap test on our php5 servers and it was positive (soap ext enabled). On the php4 server with nusoap the soap test is irrelevant but I've made changes to the module code to accomodate the nusoap specifics. Thanks.
  3. TpEnEpETE

    FedEx - Web Services v9

    I'm getting the following response (var_dump'ed) when tryng to issue getRates (line 271 of fedexwebservices.php): array(3) { ["faultcode"]=> string(14) "soapenv:Server" ["faultstring"]=> string(46) "Internal system error. Please try again later." ["detail"]=> array(1) { ["fault"]=> array(2) { ["errorCode"]=> string(1) "2" ["reason"]=> string(46) "Internal system error. Please try again later." } } } Tested on the following systems: OsCommerce 2.2rc2a (php5, soap, win and centos4) CRE Loaded 6.15 (php4, nuSoap, centos4) I've tried both test and production credentials on all systems. I've checked the request xml. All credentials are being passed correctly. Please help...
×