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

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.

Related

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 call to WCF - soap header issue

I am making some PHP application and I want to use my WCF service, which is working good. I need to make soap call, and set header to something like this:
<s:Header>
<a:Action s:mustUnderstand="1">GetPage</a:Action>
<a:MessageID>1</a:MessageID>
<a:ReplyTo>
<a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
</a:ReplyTo>
<a:To s:mustUnderstand="1">http://someurl.com</a:To>
In my php file where I want to make the call I have:
$ns = 'http://www.w3.org/2005/08/addressing'; //Namespace of the WS.
//Body of the Soap Header.
$headerbody = array('MessageID' => '1',
'Action' => 'GetPage',
'To' => 'http://someurl.com');
//Create Soap Header.
$header = new SOAPHeader($ns, $headerbody);
//set the Headers of Soap Client.
$soapClient->__setSoapHeaders($header);
$GetPageResponse = $soapClient->GetPage($GetPageRequest);
When I go to the logs of my service, I see that the message that came in looks like:
<SOAP-ENV:Envelope xmlns:SOAP- ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:Flow/2012/10">
<SOAP-ENV:Header>
<To SOAP-ENV:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://someurl.com</To>
<Action SOAP-ENV:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">urn:Flow/2012/10/GetPage</Action>
</SOAP-ENV:Header>
</SOAP-ENV:Envelope>
$GetPageRequest is for now irrelevant. So, in my header there is no MessageID. What am I missing here? Did I set something wrong? Also, how to correctly set part 'ReplyTo'?
Not sure why MessageID is not getting through in your output yet, but adding ReplyTo->Address is as simple as adding an sub-array to your header array.
$headerbody = array('MessageID' => '1',
'Action' => 'GetPage',
'To' => 'http://someurl.com',
'ReplyTo' => array (
'Address' => 'http://www.w3.org/2005/08/addressing/anonymous'
)
);

DHL, PHP SOAP rate implementation not working

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

soapheader authenticate using php [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
PHP SoapClient and a complex header
I have this header structure:
<soapenv:Header>
<wsse:Security xmlns:wsse=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd” soapenv:mustUnderstand=”0”>
<wsse:UsernameToken>
<wsse:Username Type=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken”>votre_login</wsse:Username>
<wsse:Password Type=”http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText”>votre_password</wsse:Password>
</wsse:UsernameToken>
</wsse :Security>
</soapenv :Header>
How I put this in php using __setSoapHeaders() method?
I tried:
$auth = array(
'UsernameToken' => array(
'Username' => '*****',
'Password' => '*****'
)
);
$header = new SoapHeader('http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd','Security',$auth, 0);
$client->__setSoapHeaders($header);
and I have this error:
com.ibm.wsspi.wssecurity.SoapSecurityException: WSEC5509E: Un jeton de
sécurité dont le type est
[http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken]
est requis.
From: http://php.net/manual/en/soapclient.setsoapheaders.php#93460
To create complex SOAP Headers, you can do something like this:
Required SOAP Header:
<soap:Header>
<RequestorCredentials xmlns="http://namespace.example.com/">
<Token>string</Token>
<Version>string</Version>
<MerchantID>string</MerchantID>
<UserCredentials>
<UserID>string</UserID>
<Password>string</Password>
</UserCredentials>
</RequestorCredentials>
</soap:Header>
Corresponding PHP code:
$ns = 'http://namespace.example.com/'; //Namespace of the WS.
//Body of the Soap Header.
$headerbody = array('Token' => $someToken,
'Version' => $someVersion,
'MerchantID'=>$someMerchantId,
'UserCredentials'=>array('UserID'=>$UserID,
'Password'=>$Pwd));
//Create Soap Header.
$header = new SOAPHeader($ns, 'RequestorCredentials', $headerbody);
//set the Headers of Soap Client.
$soap_client->__setSoapHeaders($header);

Categories