How to create a PHP SOAP request with multiple namespaces

I am trying to get a quote from a SOAP service. I was able to successfully create authentication headers and request a SOAP service with basic requests that do not require body parameters.

I can create the correct structure for the query, but the namespace values ​​do not appear in the query output.

Code example:

$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(); 

The above works just fine and returns true if the delivery service is available.

Therefore, I use the following code to create the body of the request (only filling in the required fields): I also tried to put everything into an array and converted it to SoapVar, I tried to include ns1: and ns2: in the creation of the body request, but that did not work either. I believe that something needs to be corrected in the creation of the request ... I'm not sure of the best approach.

 $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; 

And he creates the following 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> 

But the output should contain namespaces (web: and web1: where necessary). The above query returns the error code of the missing tariff name.

Here is an example of what the xml request should look like:

  <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> 

Any suggestions / direction appreciated!

+6
source share
1 answer

Okay ... After too many hours of testing, I finally have a solution.

I recreated the authorization token as a class and created a Soap request without having to deal with any namespaces, SoapVars, etc., it is surprisingly easy.

 /* 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; } 
+6
source

Source: https://habr.com/ru/post/888077/


All Articles