What do I need:
I need some help figuring out an error that i receive from calling a function from a WSDL file with soapclient. Or I would like some help extracting data from a cURL response.
What am I trying to reach:
I am trying to reach to call a function from a WSDL, and get a response from the action.
What are my experiences:
I can call the actions storeOrders succesfull with a cURL statement, I do also get a response.
But with the given response i guess a string. I am not able to extract the data out of it.
So I tried to request the same action from the server but then using soapclient, but I keep getting a error.
What I already tried:
I tried to make the cURL response a new SimpleXMLElement, but it always returns a emty object. Also when I try to reach one of the children.
I tried to make the cURL reponse return as an array and loop trough it with a foreach, also here I got an empty object.
I tried to explode the cURL reponse, but also there i had some problems with the wrong data being returned.
I tried to call it with SoapClient, but I keep getting this error.
So I would like some help with extracting data from cURL, or processing the request with SoapClient.
My cURL request (with answer, all the variables are set with the correct data):
function storeOrderAndGetLabel($delisId, $auth_token, $messageLanguage, $printerLanguage, $paperFormat, $identificationNumber,
$sendingDepot, $product, $mpsCompleteDelivery, $send_name, $send_street, $send_country, $send_zipcode, $send_city,
$send_customerNumber, $rec_name, $rec_street, $rec_state, $rec_country, $rec_zipcode, $rec_city, $parcelLabelNumber,
$orderType)
{
$xml = '
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="http://dpd.com/common/service/types/Authentication/2.0" xmlns:ns1="http://dpd.com/common/service/types/ShipmentService/3.1">
<soapenv:Header>
<ns:authentication>
<delisId>'.$delisId.'</delisId>
<authToken>'.$auth_token.'</authToken>
<messageLanguage>'.$messageLanguage.'</messageLanguage>
</ns:authentication>
</soapenv:Header>
<soapenv:Body>
<ns1:storeOrders>
<printOptions>
<printerLanguage>'.$printerLanguage.'</printerLanguage>
<paperFormat>'.$paperFormat.'</paperFormat>
</printOptions>
<order>
<generalShipmentData>
<identificationNumber>'.$identificationNumber.'</identificationNumber>
<sendingDepot>'.$sendingDepot.'</sendingDepot>
<product>'.$product.'</product>
<mpsCompleteDelivery>'.$mpsCompleteDelivery.'</mpsCompleteDelivery>
<sender>
<name1>'.$send_name.'</name1>
<street>'.$send_street.'</street>
<country>'.$send_country.'</country>
<zipCode>'.$send_zipcode.'</zipCode>
<city>'.$send_city.'</city>
<customerNumber>'.$send_customerNumber.'</customerNumber>
</sender>
<recipient>
<name1>'.$rec_name.'</name1>
<street>'.$rec_street.'</street>
<state>'.$rec_state.'</state>
<country>'.$rec_country.'</country>
<zipCode>'.$rec_zipcode.'</zipCode>
<city>'.$rec_city.'</city>
</recipient>
</generalShipmentData>
<parcels>
<parcelLabelNumber>'.$parcelLabelNumber.'</parcelLabelNumber>
</parcels>
<productAndServiceData>
<orderType>'.$orderType.'</orderType>
</productAndServiceData>
</order>
</ns1:storeOrders>
</soapenv:Body>
</soapenv:Envelope>
';
$headers = array(
"POST HTTP/1.1",
"Content-type: application/soap+xml; charset=\"utf-8\"",
"SOAPAction: \"http://dpd.com/common/service/ShipmentService/3.1/storeOrders\"",
"Content-length: ".strlen($xml)
);
$cl = curl_init('https://public-ws-stage.dpd.com/services/ShipmentService/V3_1/');
curl_setopt($cl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($cl, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($cl, CURLOPT_POST, 1);
curl_setopt($cl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($cl, CURLOPT_POSTFIELDS, "$xml");
curl_setopt($cl, CURLOPT_RETURNTRANSFER, 1);
$output_cl = json_decode(trim(json_encode(curl_exec($cl))), TRUE);
return $output_cl;
//return $output_cl;
}
And from this code i get the reponse, i guess it is a string but i don't know for sure:
<soap:envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:body>
<ns2:storeordersresponse xmlns:ns2="http://dpd.com/common/service/types/ShipmentService/3.1">
<orderresult>
<parcellabelspdf>pdfkey</parcellabelspdf>
<shipmentresponses>
<identificationnumber>identificationnumber</identificationnumber>
<mpsid>mpsid</mpsid>
<parcelinformation>
<parcellabelnumber>labelnr</parcellabelnumber>
</parcelinformation>
</shipmentresponses>
</orderresult>
</ns2:storeordersresponse>
</soap:body>
</soap:envelope>
Now my function calling the SoapClient function:
$label = storeOrderAndGetLabel($delisId, $auth_token, $messageLanguage, $printerLanguage, $paperFormat, $identificationNumber,
$sedingDepot, $product, $mpsCompleteDelivery, $send_name, $send_street, $send_country, $send_zipcode, $send_city,
$send_customerNumber, $rec_name, $rec_street, $rec_state, $rec_country, $rec_zipcode, $rec_city, $parcelLabelNumber,
$orderType);
print_r($label);
now the soap call itself:
function storeOrderAndGetLabel($delisId, $auth_token, $messageLanguage, $printerLanguage, $paperFormat, $identificationNumber,
$sendingDepot, $product, $mpsCompleteDelivery, $send_name, $send_street, $send_country, $send_zipcode, $send_city,
$send_customerNumber, $rec_name, $rec_street, $rec_state, $rec_country, $rec_zipcode, $rec_city, $parcelLabelNumber,
$orderType)
{
$client = new SoapClient('https://public-ws-stage.dpd.com/services/ShipmentService/V3_1?WSDL');
$label = $client->storeOrders
(array
(
"printOptions" => array
(
"printerLanguage" => "$printerLanguage",
"paperFormat" => "$paperFormat"
),
"order" => array
(
"generalShipmentData" => array
(
"identificationNumber" => "$identificationNumber",
"sendingDepot" => "$sendingDepot",
"product" => "$product",
"mpsCompleteDelivery" => "$mpsCompleteDelivery",
"sender" => array
(
"name1" => "$send_name",
"street" => "$send_street",
"country" => "$send_country",
"zipCode" => "$send_zipcode",
"city" => "$send_city",
"customerNumber" => "$send_customerNumber"
),
"recipient" => array
(
"name1" => "$rec_name",
"street" => "$rec_street",
"state" => "$rec_state",
"country" => "$rec_country",
"zipCode" => "$rec_zipcode",
"city" => "$rec_city"
)
),
"parcels" => array
(
"parcelLabelNumber" => "$parcelLabelNumber"
),
"productAndServiceData" => array
(
"orderType" => "$orderType"
)
)
)
);
return $label;
}
The error I receive from the soapcall:
Fatal error: Uncaught SoapFault exception: [soap:Server] Fault occurred while processing. in getLabel.php:107 Stack trace: #0 getLabel.php(107): SoapClient->__call('storeOrders', Array) #1 getLabel.php(107): SoapClient->storeOrders(Array) #2 getLabel.php(38): storeOrderAndGetLabel('username', 'password...', 'nl_NL', 'PDF', 'A4', '77777', '0163', 'CL', '0', 'uname', 'straat', 'NL', 'zipcode', 'City', '341546246451...', 'Test-Empfaenger', 'Test-Strasse', 'BY', 'DE', '123451', 'ahahaha', '16231545', 'consignment') #3 {main} thrown in getLabel.php on line 107
I would like to extract the parcellabelspdf key and the mpsid from the response. It would be really nice if someone could take a look at it.
Two possible problems:
You need to authenticate when calling the DPD ShipmentService. See below for a working example.
Make sure, that the parameter mpsCompleteDelivery is passed as an integer (0), not the string "false". Consider changing this line:
"mpsCompleteDelivery" => "$mpsCompleteDelivery"
to:
"mpsCompleteDelivery" => $mpsCompleteDelivery
Here is a full example including the login and output of a DPD-label as PDF:
// Let's log in first...
$c = new SoapClient('https://public-ws-stage.dpd.com/services/LoginService/V2_0?wsdl');
$res = $c->getAuth(array(
'delisId' => 'your-Id',
'password' => 'your-Password',
'messageLanguage' => 'de_DE'
));
// ...and remember the token.
$auth = $res->return;
// ...and then generate a label
$c = new SoapClient('https://public-ws-stage.dpd.com/services/ShipmentService/V3_1?wsdl');
$token = array(
'delisId' => $auth->delisId,
'authToken' => $auth->authToken,
'messageLanguage' => 'de_DE'
);
// Set the header with the authentication token
$header = new SOAPHeader('http://dpd.com/common/service/types/Authentication/2.0', 'authentication', $token);
$c->__setSoapHeaders($header);
try {
$res = $c->storeOrders( array
(
"printOptions" => array(
"paperFormat" => "A4",
"printerLanguage" => "PDF"
),
"order" => array(
"generalShipmentData" => array(
"sendingDepot" => $auth->depot,
"product" => "CL",
"mpsCompleteDelivery" => false,
"sender" => array(
"name1" => "Sender Name",
"street" => "Sender Street 2",
"country" => "DE",
"zipCode" => "65189",
"city" => "Wiesbaden",
"customerNumber" => "123456789"
),
"recipient" => array(
"name1" => "John Malone",
"street" => "Johns Street 34",
"country" => "DE",
"zipCode" => "65201",
"city" => "Wiesbaden"
)
),
"parcels" => array(
"parcelLabelNumber" => "09123829120"
),
"productAndServiceData" => array(
"orderType" => "consignment"
)
)
)
);
} catch (SoapFault $exception) {
echo $exception->getMessage();
die();
}
// Et voilà!
header('Content-type: application/pdf');
echo $res->orderResult->parcellabelsPDF;
Check here for more information:
http://labor.99grad.de/2014/10/05/deutscher-paket-dienst-dpd-soap-schnittstelle-mit-php-nutzen-um-versandetikett-als-pdf-zu-generieren/
I have a Webservice WSDL with NuSoap. I use it with CodeIgniter. I have problems with contexttype-array returns. Here is my PHP Code:
$this->nusoap_server->wsdl->addComplexType(
"getJobStatusByIdsResponse",
"complexType",
"array",
"all",
"SOAP-ENC:Array",
array(),
array(
'Job' => array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:jobStatusResponse[]', 'minOccurs'=>'1', 'maxOccurs'=>'unbounded')
),
'tns:jobStatusResponse'
);
$this->nusoap_server->wsdl->addComplexType(
"getJobStatusByIdsResponse",
"complexType",
"array",
"all",
"SOAP-ENC:Array",
array(),
array(
'Job' => array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'tns:jobStatusResponse[]', 'minOccurs'=>'1', 'maxOccurs'=>'unbounded')
),
'tns:jobStatusResponse'
);
$this->nusoap_server->register(
"getJobStatusByIds",
array('getJobStatusByIdsRequest' => 'tns:getJobStatusByIdsRequest'),
array('getJobStatusByIdsResponse' => 'tns:getJobStatusByIdsResponse'),
false,
false,
"rpc",
"literal",
"get JobStatus By Ids"
);
function getJobStatusByIds($data) {
return array(array('orderId' => '1000', 'jobStatus' => '5'),array('orderId' => '1001', 'jobStatus' => '3'),array('orderId' => '1002', 'jobStatus' => '7'))
}
I get this as return:
<ns1:getJobStatusByIdsResponse xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/">
<getJobStatusByIdsResponse>
<item>
<orderId>1001</orderId>
<jobStatus>5</jobStatus>
</item>
<item>
<orderId>1002</orderId>
<jobStatus>3</jobStatus>
</item>
<item>
<orderId>1003</orderId>
<jobStatus>7</jobStatus>
</item>
</getJobStatusByIdsResponse>
</ns1:getJobStatusByIdsResponse>
That not right, isn't it?
How can i get it like this ('Job' instead of 'item'):
<ns1:getJobStatusByIdsResponse xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/">
<getJobStatusByIdsResponse>
<Job>
<orderId>1001</orderId>
<jobStatus>5</jobStatus>
</Job>
<Job>
<orderId>1002</orderId>
<jobStatus>3</jobStatus>
</Job>
<Job>
<orderId>1003</orderId>
<jobStatus>7</jobStatus>
</Job>
</getJobStatusByIdsResponse>
</ns1:getJobStatusByIdsResponse>
Who can me help?
Where can I find more examples for NuSoap?
Hope this helps.
Added the code comments to help for those that have trouble remembering the NuSoap params off hand.
$this->nusoap_server->register(
"getJobStatusByIds", // method name
array('getJobStatusByIdsRequest' => 'tns:getJobStatusByIdsRequest'), // input params
array('getJobStatusByIdsResponse' => 'tns:getJobStatusByIdsResponse'), // output params
false, // namespace
false, // soap action
"rpc", // style
"literal", // use
"get JobStatus By Ids" // documentation
);
I think the response the definition should look something like this.
// Job Status Result Complex Type (output)
$this->nusoap_server->wsdl->addComplexType(
"getJobStatusByIdsResponse",
"complexType",
"struct",
"all",
"SOAP-ENC:Array",
array('Job' => array('orderId' => 'your value here', jobStatus => 'your value here')),
);
I am working with nuSoap to build a soap server.
But i cant get the attributes the way i want.
I would like as return value:
<return xsi:type="tns:Taxatie">
<EmailAdres OptIn="1" xsi:type="tns:string">email#domain.com</EmailAdres>
</return>
And i get:
<return xsi:type="tns:Taxatie">
<EmailAdres OptIn="1" xsi:type="tns:EmailAdres">
<EmailAdres xsi:type="xsd:string">email#domain.com</EmailAdres>
</EmailAdres>
</return>
anyone know what i must change?
Or how I should set up the arrays?
This is my test code:
<?php
require_once("nusoap.php");
$soapserver = new nusoap_server();
$soapserver->configureWSDL('thijs.test', 'urn:thijs.test');
$soapserver->wsdl->addComplexType(
'Taxatie',
'complexType',
'struct',
'all',
'',
array(
'EmailAdres' => array('name' => 'EmailAdres', 'type' => 'tns:EmailAdres')
)
);
$soapserver->wsdl->addComplexType(
'EmailAdres',
'simpleType',
'struct',
'all',
'',
array(
"EmailAdres" => array('name' => 'EmailAdres', 'type' => 'xsd:string', 'minOccurs' => 0)
),
array(
'OptIn' => array('name' => 'OptIn', 'type' => 'xsd:boolean', 'use' => 'required')
)
);
$soapserver->register('taxatie', // method name
array(), // input parameters
array('return' => 'tns:Taxatie'), // output parameters
'urn:thijs.test', // namespace
'urn:thijs.test#taxatie', // soapaction
'rpc', // style
'encoded', // use
'return something' // documentation
);
class taxatie
{
var $EmailAdres = null;
function taxatie()
{
$this->EmailAdres = new emailadres();
}
}
class emailadres
{
var $EmailAdres = 'email#domain.com';
var $OptIn = true;
}
function taxatie()
{
return new taxatie();
}
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$soapserver->service($HTTP_RAW_POST_DATA);
Thanks in advance
Why not simply return an array instead of using complex type?
e.g
$resultarray['taxatie'] = array(
'EmailAdres' => $row["EmailAdres"],
'tagcount' => $row["tagcount"],
'OptIn' => $row["OptIn"]
);
i have created a simple web service using Php Nusoap. its working correctly but the only thing missing is to add the default xmlns attribute to the response tag.
Here is the copy of Response :
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<LoginResponse xmlns="">
<LoginResult>
<register>
<customer>d2ff3b88d34705e01d150c21fa7bde07</customer>
</register>
</LoginResult>
</LoginResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Here is the code :
<?php
require_once ('nusoap.php');
// set namespace
$ns = 'mynamspace';
// set up soap server
$server = new soap_server ();
$server->configureWSDL ( 'testservice', $ns);
$server->wsdl->schemaTargetNamespace = $ns;
// define new user data type
// define results
$server->wsdl->addComplexType ( 'customer', 'complexType', 'struct', '', '', array ('customer' => array ('name' => 'customer', 'type' => 'xsd:string' ) ) );
$server->wsdl->addComplexType ( 'register', 'complexType', 'struct', '', '', array ('register' => array ('name' => 'register', 'type' => 'tns:customer' ) ) );
$server->wsdl->addComplexType ( 'LoginResult', 'complexType', 'struct', '', '', array ('LoginResult' => array ('name' => 'LoginResult', 'type' => 'tns:register' ) ) );
// register Login function
$server->register ( 'Login', // method name
array ('username' => 'xsd:string', 'password' => 'xsd:string' ), // input parameters
array ('LoginResult' => 'tns:register' ), // output parameters
'urn:mynamespace', // namespace
'urn:mynamespaceAction', // soapaction
'document', // style
'literal', // use
'Login service for testing' ); // documentation
function Login($username, $password) {
if (isset ( $username ) && isset ( $password )) {
$hash = md5 ( $username );
return array ('LoginResult' => array ('register' => array ('customer' => $hash ) ));
}
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset ( $HTTP_RAW_POST_DATA ) ? $HTTP_RAW_POST_DATA : '';
$server->service ( $HTTP_RAW_POST_DATA );
?>
Any help is greatly appreciated.
I don't claim this is particularly elegant, but worked in my case:
I went into the nusoap.php and commented this line (line 5925 for me):
//$elementNS = " xmlns=\"\"";
directly after this:
if ($unqualified && $use == 'literal') {