2011-05-13 26 views
6

Estoy intentando obtener una cotización de envío de un servicio SOAP. Pude crear con éxito encabezados de autenticación y consultar el servicio SOAP con solicitudes básicas que no requieren parámetros corporales.Cómo crear una solicitud SOAP de PHP con varios espacios de nombres

Soy capaz de crear la estructura adecuada para la solicitud pero los valores del espacio de nombres no se muestran en el resultado de la solicitud.

código Ejemplo:

$client = new SoapClient("http://demo.smc3.com/AdminManager/services/RateWareXL?wsdl", 
        array('trace' => TRUE)); 

$headerParams = array('ns1:licenseKey' => $key, 
         'ns1:password'  => $pass, 
         'ns1:username'  => $user); 

$soapStruct = new SoapVar($headerParams, SOAP_ENC_OBJECT); 
$header = new SoapHeader($ns, 'AuthenticationToken', $soapStruct, false); 
$client->__setSoapHeaders($header); 

// Check if shipping is ready - base call 
$ready_to_ship = $client->isReady(); 

lo anterior funciona bien y devuelve verdadero si el servicio de envío está disponible.

Así que utilizo el siguiente código para crear el cuerpo de la solicitud (solo llenando los campos obligatorios): También intenté poner todo en una matriz y convertir eso a SoapVar, intenté incluir ns1: y ns2: en la creación de solicitud de cuerpo, pero eso tampoco funcionó. Creo que algo necesita ser ajustado en la creación petición ... no estoy seguro de la mejor manera ..

$rate_request = $client->LTLRateShipment; 
$rate_request->LTLRateShipmentRequest->destinationCountry = $destination_country; 
$rate_request->LTLRateShipmentRequest->destinationPostalCode = $destination_postal_code; 
$rate_request->LTLRateShipmentRequest->destinationPostalCode = $destination_postal_code; 
$rate_request->LTLRateShipmentRequest->details->LTLRequestDetail->nmfcClass = $ship_class; 
$rate_request->LTLRateShipmentRequest->details->LTLRequestDetail->weight = $ship_weight; 
$rate_request->LTLRateShipmentRequest->originCountry = $origin_country; 
$rate_request->LTLRateShipmentRequest->originPostalCode = $origin_postal_code; 
$rate_request->LTLRateShipmentRequest->shipmentDateCCYYMMDD = $ship_date; 
$rate_request->LTLRateShipmentRequest->tariffName = $tariff; 

y produce el siguiente código XML:

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://webservices.smc.com"> 
     <SOAP-ENV:Header> 
      <ns1:AuthenticationToken> 
       <ns1:licenseKey>xxxxxxxx</ns1:licenseKey> 
       <ns1:password>xxxxxxxx</ns1:password> 
       <ns1:username>xxxxxxxxm</ns1:username> 
        </ns1:AuthenticationToken> 
    </SOAP-ENV:Header> 
    <SOAP-ENV:Body> 
     <ns1:LTLRateShipment> 
      <LTLRateShipmentRequest> 
       <destinationCountry>USA</destinationCountry> 
       <destinationPostalCode>10001</destinationPostalCode> 
     <details> 
       <LTLRequestDetail> 
      <nmfcClass>60</nmfcClass> 
      <weight>300</weight> 
          </LTLRequestDetail> 
     </details> 
          <originCountry>USA</originCountry> 
       <originPostalCode>90210</originPostalCode> 
       <shipmentDateCCYYMMDD>20110516</shipmentDateCCYYMMDD> 
       <tariffName>DEMOLTLA</tariffName> 
      </LTLRateShipmentRequest> 
     </ns1:LTLRateShipment> 
    </SOAP-ENV:Body> 
    </SOAP-ENV:Envelope> 

Pero la salida debe incluir los espacios de nombres (web: y web1: según corresponda). La solicitud anterior devuelve un código de error de la falta de tariffName.

He aquí un ejemplo de lo que la solicitud XML debe verse como:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:web="http://webservices.smc.com" xmlns:web1="http://web.ltl.smc.com"> 
    <soapenv:Header> 
     <web:AuthenticationToken> 
     <web:licenseKey> string </web:licenseKey> 
     <web:password> string </web:password> 
     <web:username> string </web:username> 
     </web:AuthenticationToken> 
    </soapenv:Header> 
    <soapenv:Body> 
     <web:LTLRateShipment> 
     <web:LTLRateShipmentRequest> 
      <web1:LTL_Surcharge> string </web1:LTL_Surcharge> 
      <web1:TL_Surcharge> string </web1:TL_Surcharge> 
      <web1:destinationCity> string </web1:destinationCity> 
      <web1:destinationCountry> string </web1:destinationCountry> 
      <web1:destinationPostalCode> string </web1:destinationPostalCode> 
      <web1:destinationState> string </web1:destinationState> 
      <web1:details> 
       <!--Zero or more repetitions:--> 
       <web1:LTLRequestDetail> 
        <web1:nmfcClass> string </web1:nmfcClass> 
        <web1:weight> string </web1:weight> 
       </web1:LTLRequestDetail> 
      </web1:details> 
      <web1:discountApplication> string </web1:discountApplication> 
      <web1:mcDiscount> string </web1:mcDiscount> 
      <web1:orgDestToGateWayPointFlag> string </web1:orgDestToGateWayPointFlag> 
      <web1:originCity> string </web1:originCity> 
      <web1:originCountry> string </web1:originCountry> 
      <web1:originPostalCode> string </web1:originPostalCode> 
      <web1:originState> string </web1:originState> 
      <web1:rateAdjustmentFactor> string </web1:rateAdjustmentFactor> 
      <web1:shipmentDateCCYYMMDD> string </web1:shipmentDateCCYYMMDD> 
      <web1:shipmentID> string </web1:shipmentID> 
      <web1:stopAlternationWeight> string </web1:stopAlternationWeight> 
      <web1:surchargeApplication> string </web1:surchargeApplication> 
      <web1:tariffName> string </web1:tariffName> 
      <web1:weightBreak_Discount_1> string </web1:weightBreak_Discount_1> 
     </web:LTLRateShipmentRequest> 
     </web:LTLRateShipment> 
    </soapenv:Body> 
</soapenv:Envelope> 

alguna sugerencia/dirección apreciado!

Respuesta

6

bien ... Después de muchas horas de pruebas que finalmente tienen una solución ..

I recreado la Autorización de emergencia como clase y construido la solicitud SOAP sin tener que hacer frente a cualquier espacio de nombres, etc. Es SoapVars sorprendentemente fácil.

/* Object for holding authentication info 
    this could probably be accomplished using stdClass too */ 
class AuthHeader { 
    var $licenseKey; 
    var $password; 
    var $username; 

    function __construct($loginInfo) { 
     $this->licenseKey = $loginInfo['licenseKey']; 
     $this->password = $loginInfo['password']; 
     $this->username = $loginInfo['username']; 
    } 
} 

// set current soap header with login info 
$client = new SoapClient("http://demo.smc3.com/AdminManager/services/RateWareXL?wsdl", 
        array('trace' => TRUE 
         )); 
// create header params array 
$headerParams = array('licenseKey'  => $key, 
         'password'   => $pass, 
         'username'   => $user); 
// create AuthHeader object 
$auth = new AuthHeader($headerParams); 

// Turn auth header into a SOAP Header 
$header = new SoapHeader($ns, 'AuthenticationToken', $auth, false); 

// set the header 
$client->__setSoapHeaders($header); 

// Check if shipping is ready - base call 
$ready_to_ship = $client->isReady(); 
// $last_request = $client->__getLastRequest(); 
$last_response = $client->__getLastResponse(); 

//print $last_request; 
if ($last_response == true) { 

    print "Ready to ship\n"; 

// Create the shipping request 
$d = new stdClass; 
$d->nmfcClass = $ship_class; 
$d->weight = $ship_weight; 

$p = new stdClass; 
$p->LTLRateShipmentRequest->destinationCountry  = $destination_country; 
$p->LTLRateShipmentRequest->destinationPostalCode = $destination_postal_code; 
$p->LTLRateShipmentRequest->details     = array($d); 
$p->LTLRateShipmentRequest->originCountry   = $origin_country; 
$p->LTLRateShipmentRequest->originPostalCode   = $origin_postal_code; 
$p->LTLRateShipmentRequest->shipmentDateCCYYMMDD  = $ship_date; 
$p->LTLRateShipmentRequest->tariffName    = $tariff; 

$quote = $client->LTLRateShipment($p); 

$last_request = $client->__getLastRequest(); 
$last_response = $client->__getLastResponse(); 

print "Request: " . $last_request; 
print "\nResponse: " . $last_response; 

} 
Cuestiones relacionadas