DHL, PHP SOAP rate implementation not working - php

You are my last hope!
I'm trying to implement DHL'S rating API to a website.
They send to me the sample code, I tried it to the demo environment with demo credentials and it worked fine.
Later they change the endpoint url and send to me the permanent credentials.
After that I can't make it to work. I'm getting the following error:
SOAP Fault!
FaultCode: WSDL FaultString: SOAP-ERROR: Parsing WSDL: Couldn't load
from 'https://wsbexpress.dhl.com:443/gbl/expressRateBook' : failed to
load external entity
My PHP code goes like this:
<?php
// The url of the service
$url='https://wsbexpress.dhl.com:443/gbl/expressRateBook';
// the soap operation which is called
$action='euExpressRateBook_providerServices_ShipmentHandlingServices_Binder_getRateRequest';
// the xml input of the service
$xmlrequest='<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rat="http://scxgxtt.phx-dc.dhl.com/euExpressRateBook/RateMsgRequest">
<soapenv:Header>
<wsse:Security soapenv:mustunderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken wsu:id="UsernameToken-5" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<!-- ####Please use your test user credentials here#### -->
<wsse:Username>*************</wsse:Username>
<!-- ####Please use your test user credentials here#### -->
<wsse:Password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">*************</wsse:Password>
<wsse:Nonce encodingtype="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">eUYebYfsjztETJ4Urt8AJw==</wsse:Nonce>
<wsu:Created>2010-02-12T17:40:39.124Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
<soapenv:Header/>
<soapenv:Body>
<rat:RateRequest>
<RequestedShipment>
<DropOffType>REGULAR_PICKUP</DropOffType>
<Account>*********</Account>
<Currency>EUR</Currency>
<UnitOfMeasurement>SI</UnitOfMeasurement>
<Ship>
<Shipper>
<StreetLines>TEST SHIPPER</StreetLines>
<City>ALIMOS</City>
<PostalCode>174 55</PostalCode>
<CountryCode>GR</CountryCode>
</Shipper>
<Recipient>
<StreetLines>Main Street</StreetLines>
<City>GENEVA</City>
<PostalCode>1201</PostalCode>
<CountryCode>CH</CountryCode>
</Recipient>
</Ship>
<Packages>
<RequestedPackages number="1">
<Weight>
<Value>0.5</Value>
</Weight>
<Dimensions>
<Length>3</Length>
<Width>2</Width>
<Height>1</Height>
</Dimensions>
</RequestedPackages>
</Packages>
<ShipTimestamp>2015-12-28T00:01:00GMT+00:00</ShipTimestamp>
<Content>NON_DOCUMENTS</Content>
<PaymentInfo>DAP</PaymentInfo>
</RequestedShipment>
</rat:RateRequest>
</soapenv:Body>
</soapenv:Envelope>';
try {
// the soap client accepts options, we specify the soap version
// The trace option enables tracing of request so faults can be backtraced.
// The exceptions option is a boolean value defining whether soap errors throw exceptions of type SoapFault.
$options = array(
'soap_version'=>SOAP_1_1,
'exceptions'=>true,
'trace'=>1,
);
// create the soapclient and invoke __doRequest method
$client = new SoapClient($url, $options);
$output= $client->__doRequest($xmlrequest, $url, $action, 1);
}
catch (SoapFault $fault) {
echo "<h2>SOAP Fault!</h2><p>";
echo "FaultCode: {$fault->faultcode} <br/>";
echo "FaultString: {$fault->faultstring} <br/>";
echo("</p/>");
}
echo ("<h2>WSDL URL: </h2><p>");
echo ($url);
echo("</p/>");
echo ("<h2>Action: </h2><p>");
echo ($action);
echo("</p/>");
echo("<h2>XMLRequest: </h2><p>");
echo ($xmlrequest);
echo("</p/>");
if (!isset($output)) {
echo "<h2>SOAP Fault!</h2><p>";
echo "FaultCode: {$output->faultcode} <br/>";
echo "FaultString: {$output->faultstring} <br/>";
}else{
echo("<h2>Output: </h2><p>");
echo $output;
echo("</p/>");
}
?>
Where ********* my actual credentials.
If I give as endpoint url
https://wsbexpress.dhl.com/gbl/expressRateBook?wsdl
I'm getting as response the SOAP schema.
Could you help to find out whats wrong and I'm no getting the right response?

Try to experiment with options like this:
$opts = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
$options = array (
'encoding' => 'UTF-8',
'verifypeer' => false,
'verifyhost' => false,
'soap_version' => SOAP_1_2,
'trace' => 1,
'exceptions' => 1,
'connection_timeout' => 180,
'stream_context' => stream_context_create($opts),
'cache_wsdl' => WSDL_CACHE_NONE,
//'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP | 1
);

Related

SOAP Integration into WP PHP Plugin

I'm tasked at using SOAP to pull in data through a WP Plugin for ease of use. I'm stuck at using the supplied auth details to get the correct data. I'm using SOAPUI to explore the request and see the possible methods/calls.
The flow should be using the FetchNewListingsIds which will give me a list of IDS which I can then put into an array object and then use that again for FetchListings with the supplied IDs - that will then give me all the details for each listing which I can then take and pull in to display
This is what I've written so far:
function property_feed_call(){
$url = "https://exdev.server.propctrl.com/v5.4/Basic/AgencyIntegration.svc?wsdl";
$user = "MindesExdevFeedUser";
$pass = "MindesExdevFeedUser";
$options = [
'cache_wsdl' => WSDL_CACHE_NONE,
'trace' => 1,
'stream_context' => stream_context_create(
[
'ssl' => [
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
]
]
)
];
// Set request params
$params = array(
"Username" => $user,
"Password" => $pass,
);
$client = new SoapClient($url, $options);
$session = $client->FetchNewListingIds($params);
// Invoke WS method (Function1) with the request params
$response = $client->__soapCall("FetchListings", array($params));
// Print WS response
echo '<pre>';
print_r($session);
echo '</pre>';
}
An example of how the request looks (FetchListings) when I open it up with SOAPUI is:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v5="http://server.propctrl.com/v5_4" xmlns:ais="http://server.propctrl.com/v5_4/AIS" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<soapenv:Header>
<v5:Credentials>
<!--Optional:-->
<v5:Password>?</v5:Password>
<!--Optional:-->
<v5:Username>?</v5:Username>
</v5:Credentials>
</soapenv:Header>
<soapenv:Body>
<ais:FetchListings>
<!--Optional:-->
<ais:mandateIds>
<!--Zero or more repetitions:-->
<arr:int>?</arr:int>
</ais:mandateIds>
</ais:FetchListings>
</soapenv:Body>
</soapenv:Envelope>
So you can see its asking for Credentials which I have just not sure how to pass it to my request. And then for a mandateIds which I can get from another method that also requires the same Credentials.

PHP SOAP client not creating body

After over a half a day of trying and reading tutorials on creating a simple SOAP client, I am no closer to retrieving a request from API I attempting to work with.
WSDL: http://publicapi.ekmpowershop31.com/v1.1/publicapi.asmx?WSDL
I can make the request from SOAP UI with the following simple SOAP request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pub="http://publicapi.ekmpowershop.com/">
<soapenv:Header/>
<soapenv:Body>
<pub:GetOrders>
<!--Optional:-->
<pub:GetOrdersRequest>
<!--Optional:-->
<pub:APIKey>myApiKey</pub:APIKey>
</pub:GetOrdersRequest>
</pub:GetOrders>
</soapenv:Body>
</soapenv:Envelope>
This above returns the expected data.
When it comes to translating the request into a PHP I have the following:
$wsdl = 'http://publicapi.ekmpowershop31.com/v1.1/publicapi.asmx?WSDL';
$trace = true;
$exceptions = false;
$debug = true;
$client = new SoapClient($wsdl,
array(
'trace' => $trace,
'exceptions' => $exceptions,
'debug' => $debug,
));
$param = array('GetOrdersRequest' => array(
'APIKey' => 'myApiKey'
)
);
$resp = $client->GetOrders();
print_r($param);
print_r($client->__getLastRequest());
print_r($client->__getLastResponse());
If put the $param into the GetOrders function then, it breaks and nothing happens.
Even if I use an array in the $client->GetOrders(array('someArry' => $param)) then response and request still always looks the same and looks like the body of the SOAP request is never created:
Request:
?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://publicapi.ekmpowershop.com/"><SOAP-ENV:Body><ns1:GetOrders/></SOAP-ENV:Body></SOAP-ENV:Envelope>
Response:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetOrdersResponse xmlns="http://publicapi.ekmpowershop.com/"><GetOrdersResult><Status>Failure</Status><Errors><string>Object reference not set to an instance of an object.</string></Errors><Date>2017-04-03T16:00:42.9457446+01:00</Date><TotalOrders>0</TotalOrders><TotalCost xsi:nil="true" /></GetOrdersResult></GetOrdersResponse></soap:Body></soap:Envelope>
If anyone can shed some light on what I am doing wrong here that would be real big help?
P.S My experience of SOAP in PHP is limited as I am used to SOAP in a java env. Thanks
You need to pass the parameters into the $client->GetOrders() call. Also the WSDL defines some required parameters, so a minimal example is something like:
$wsdl = 'http://publicapi.ekmpowershop31.com/v1.1/publicapi.asmx?WSDL';
$trace = true;
$exceptions = false;
$debug = true;
$client = new SoapClient($wsdl,
array(
'trace' => $trace,
'exceptions' => $exceptions,
'debug' => $debug,
));
$param = array(
'GetOrdersRequest' => array(
'APIKey' => 'dummy-key',
'CustomerID' => 1,
'ItemsPerPage' => 1,
'PageNumber' => 1,
)
);
$resp = $client->GetOrders($param);
print_r($param);
print_r($client->__getLastRequest());
print_r($client->__getLastResponse());
This gives the error response:
<Errors><string>Invalid character in a Base-64 string.</string></Errors>
which presumably is because my API key is invalid.

Set xml rquest header in non-wsdl soap client using php

I am trying to make a non-wsdl SOAP client call using php. My code is something like this:
try {
$URL = 'http://example.com/webservices/security/accesscontrol.asmx';
$sc = new SoapClient(null, array(
'location' => $URL,
'uri' => 'http://example.com/webservices/security/',
'trace' => 1
));
$usertoken = array('UserNameToken' =>
array(
'UserName' => 'test',
'Password' => 'test123'
));
$header = new SoapHeader('http://www.docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', 'Security', $usertoken);
$sc->__setSoapHeaders($header);
$test = $sc->__soapCall("AuthenticateClient",
array(),
array('soapaction' => 'http://example.com/webservices/security/AuthenticateClient')
);
If I debug and see the Last request header part of xml it looks like this:
<SOAP-ENV:Header>
<ns2:Security>
<item><key>UserNameToken</key><value><item><key>UserName</key><value>test</value></item><item><key>Password</key><value>test123</value></item></value></item>
</ns2:Security>
</SOAP-ENV:Header>
But if I use wsdl file, the xml header looks like this:
<SOAP-ENV:Header>
<ns2:Security>
<ns2:UserNameToken>
<ns2:UserName>test</ns2:UserName>
<ns2:Password>test123</ns2:Password>
</ns2:UserNameToken>
</ns2:Security>
</SOAP-ENV:Header>
How can I make the header part like above using non-wsdl SOAP client call? Becasue its not working and giving an error that is caused by "if either the UserName Token or the UserName was not provided in the AuthenticateClient Soap Header Request"
Thanks in advance for your help.
Please note that I have changed the URL and password intentionally as I can not disclose them.
You can create the part of the header manually and insert it into the SoapHeader, try to do something like this:
$URL = 'http://example.com/webservices/security/accesscontrol.asmx';
$soapClient = new SoapClient(null, array(
'location' => $URL,
'uri' => 'http://example.com/webservices/security/',
'trace' => 1
));
$headerPart = '
<SOAP-ENV:Header>
<ns2:Security>
<ns2:UserNameToken>
<ns2:UserName>DASKO</ns2:UserName>
<ns2:Password>welcome1</ns2:Password>
</ns2:UserNameToken>
</ns2:Security>
</SOAP-ENV:Header>
';
$soapVarHeader = new SoapVar($headerPart, XSD_ANYXML, null, null, null);
$header = new SoapHeader(
'http://www.docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', // Namespace - namespace of the WebService
'Security',
$soapVarHeader,
false // mustunderstand
);
$soapClient->__setSoapHeaders($header);

PHP: Webservice error SoapClient

Request from SoapUI
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:not="http://xxx.xxx.xxx.com/">
<soapenv:Header/>
<soapenv:Body>
<not:SaasNotificationResponse>
<hostID>UCALL</hostID>
<orderID>1180000335810000000010</orderID>
<custID>1180000335770000000010</custID>
<typeTransaction>SUSPENSION</typeTransaction>
<status>3</status>
<message>SUSPENSION 1180000335770000000010</message>
<notifyAttr>
<name>?</name>
<value>?</value>
</notifyAttr>
</not:SaasNotificationResponse>
</soapenv:Body>
</soapenv:Envelope>
Response From SoapUI:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:SaasNotificationResponseResponse xmlns:ns2="http://xxx.xxxx.xxx.com/">
<return>F</return>
<return>Invalid TypeTransaction</return>
</ns2:SaasNotificationResponseResponse>
</S:Body>
</S:Envelope>
Codding PHP Client;
require_once('lib/nusoap.php');
try {
$client = new SoapClient("http://xxx.xxx.xxx/Notification?WSDL");
$data = array( 'hostID' => 'UCALL',
'orderID' => '1180000335810000000010',
'custID' => '1180000335810000000010',
'typeTransaction' => 'ACTIVATION',
'status' => '3',
'message' => 'Activation complete',
'notifyAttr' => array(
array('name'=>'AccountID','value'=>'110022101010'),
array('name'=>'PackageID','value'=>'1')
)
);
$return=$client->SaasNotificationResponse($data);
//$return=$client->call('SaasNotificationResponse',($data));
print_r($return);
}catch (SoapFault $e){
echo $e;
}
Error Application.
Fatal error: Call to undefined method soapclient::SaasNotificationResponse() in C:\wamp\www\spgdtws\notification.php
I have a problem in php webservice applications. if using soapUI. webservice server can be invoked. but when I use the application on the client. error occurs. please help
It seems that you are calling notification WSDL for Telkom's service.
this code works for me
<?php
function sendNotification($orderID,$custID,$typeTransaction,$status,$message) {
try {
$client = new SoapClient("XXXXXXXXX/Notification?wsdl",array("trace"=>1,"exceptions"=>1));
$data = array( 'hostID' => '',
'orderID' => $orderID,
'custID' => $custID,
'typeTransaction' => $typeTransaction,
'status' => $status,
'message' => $message,
'notifyAttr' => array(
array('name'=>'','value'=>''),
array('name'=>'','value'=>'')
)
);
$return=$client->SaasNotificationResponse($data);
var_dump($return);
}catch (SoapFault $e){
echo $e;
}
}
sendNotification('1180000339980000000010','4720562','TERMINATION','3','TERMINATION success');
?>
You don't need to include nusoap. Use native PHP's SOAP instead. SoapClient class is belong to native PHP.
for reference :
http://php.net/manual/en/class.soapclient.php

PHP : Subnode of SOAP Header element is not found or recognized

I'm trying to call a SOAP Adonix X3 web service by using a php client.
For testing, I used SOAP UI and it worked well ; this is the xml request :
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:a="http://www.adonix.com/WSS"
xmlns:XS="http://www.w3.org/2001/XMLSchema"
xmlns:XI="http://www.w3.org/2001/XMLSchema-instance">
<S:Header>
<a:CAdxCallingContext>
<a:codeLang XI:type="XS:string">FRA</a:codeLang>
<a:codeUser XI:type="XS:string">ADM</a:codeUser>
<a:password XI:type="XS:string">XXX</a:password>
<a:poolAlias XI:type="XS:string">TEST</a:poolAlias>
<a:requestConfig XI:type="XS:string">trace</a:requestConfig>
</a:CAdxCallingContext>
</S:Header>
<S:Body>
<a:runXml S:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<publicName XI:type="XS:string">RECH_OF</publicName>
<inputXml XI:type="XS:string">
<![CDATA[
<PARAM>
<GRP ID="GRP1">
<FLD NAME="XITMREF">PSFIN00153</FLD>
<FLD NAME="XFLUX">recycle</FLD>
<FLD NAME="XOPENUM">15</FLD>
</GRP>
</PARAM>
]]>
</inputXml>
</a:runXml>
</S:Body>
</S:Envelope>
but trying to do the same call in php :
$sh_param = array(
'codeLang' => 'FRA',
'codeUser' => 'ADM',
'password' => 'XXX',
'poolAlias' => 'TEST',
'requestConfig ' => 'trace'
);
$ns = 'http://www.adonix.com/WSS';
$headers = new SoapHeader($ns, 'CAdxCallingContext', $sh_param, false);
// Prepare Soap Client
$soapClient->__setSoapHeaders(array($headers));
$at_param2 = array(
'XITMREF' => 'PSFIN00153',
'XFLUX' => 'recycle',
'XOPENUM' => '15');
// Setup the RemoteFunction parameters
$ap_param = array(
'publicName' => 'RECH_OF',
'inputXml' => array($at_param2));
$info = $soapClient->__call("runXml", array($ap_param));
I get the following error :
3 - Le Header element [http://www.adonix.com/WSS][CAdxCallingContext] du message Soap n'a pas de fils [codeLang].
this means
The Header element [http://www.adonix.com/WSS][CAdxCallingContext] of the Soap message has no son [codeLang]
It seems the server doesn't find the subnode of the header...
any idea ?
Thanks
The problem you're having is because the X3 Web Service is unable to identify header parameters without the namespace reference
Moreover, you should use a SoapVar instead of the basic array to build a correct header
So you should try something like this
$ns = 'http://www.adonix.com/WSS';
$headerParams = array('ns1:codeLang' => 'FRA',
'ns1:codeUser' => 'ADM',
'ns1:password' => 'XXX',
'ns1:poolAlias' => 'TEST',
'ns1:requestConfig' => 'trace');
$soapStruct = new SoapVar($headerParams, SOAP_ENC_OBJECT);
$header = new SoapHeader($ns, 'CAdxCallingContext', $soapStruct, false);
Good Luck
Al.

Categories