I am getting a request in the following method but the soap message does not appear to contain the UsernameToken Element:
$policy = new WSPolicy(
array(
'useUsernameToken'=>true
)
);
$security = new WSSecurityToken(
array(
'user'=>$username,
'passwordType'=>'PlainText',
'password'=>$password
)
);
// create client in WSDL mode
$client = new WSClient(
array (
'wsdl'=>$service_wsdl,
'to'=>$service_url,
'policy'=>$policy,
'securityToken'=>$security,
'trace'=>1
)
);
$proxy = $client->getProxy();
$proxy->Ping();
The request that is produced looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ns1:Ping xmlns:ns1="http://streamlinedsalestax.org/efile"/>
</soapenv:Body>
</soapenv:Envelope>
You'll notice that the UsernameToken element is completely missing.
how about this.. added 'security' to WSPolicy
<?php
$policy = new WSPolicy(
array('security' => array(
'useUsernameToken'=>true
))
);
$security = new WSSecurityToken(
array(
'user'=>$username,
'passwordType'=>'PlainText',
'password'=>$password
)
);
// create client in WSDL mode
$client = new WSClient(
array (
'wsdl'=>$service_wsdl,
'to'=>$service_url,
'policy'=>$policy,
'securityToken'=>$security,
'trace'=>1
)
);
$proxy = $client->getProxy();
$proxy->Ping();
Related
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.
i've got this XML and it works in soapUi
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="xxx" xmlns:data="xxx">
<soapenv:Header/>
<soapenv:Body>
<web:FindArticles>
<web:request>
<data:culture_id>de-DE</data:culture_id>
<data:vehicle_search_parameters>
<data:address>
<!--Optional:-->
<data:countries>
<!--Zero or more repetitions:-->
<data:country_id>D</data:country_id>
</data:countries>
<!--Optional:-->
</data:address>
<data:dealer_id>XXX</data:dealer_id>
<data:show_dealer_vehicles>true</data:show_dealer_vehicles>
</data:vehicle_search_parameters>
</web:request>
</web:FindArticles>
</soapenv:Body>
</soapenv:Envelope>
But I can not fugure out how to call it via PHP. I'm trying something like this, but get errors...
<?php
$wsdl = 'XXX';
$options = array(
'login' => 'XXX',
'password' => 'XXX',
'trace'=>true
);
$params = array(
'culture_id' => 'de-DE',
'country_id' => 'D',
'dealer_id' => 'XXX',
'show_dealer_vehicles' => true
);
try {
$soap = new SoapClient($wsdl, $options);
$data = $soap->FindArticles($params);
}
catch(Exception $e) {
die($e->getMessage());
}
var_dump($data);
die;
It looks, that there is some kind of nested functions - how have I call it via PHP? I've tried smth like $soap->FindArticles('request', $params), but it still does not work
This is my WSDL XML: (Generated with SoapUI)
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://soap.test.com/">
<soapenv:Header/>
<soapenv:Body>
<ser:myMethod>
<user>
<id>?</id>
<name>?</name>
</user>
<code>?</code>
</ser:myMethod>
</soapenv:Body>
</soapenv:Envelope>
And my PHP code to consume the "myMethod" method:
$opts = array(
'location' => 'http://example.com/myServices?WSDL',
'uri' => 'http://soap.test.com'
);
$client = new SOAPClient(null, $opts);
$res = $client->__soapCall('myMethod', array(
"id" => "123",
"name" => "Sam"
));
var_dump($res);
And I get the Cannot find dispatch method for {http://soap.test.com} myMethod error.
I've tested the SOAP with SoupUI and it has responsed correctly.
What is wrong here?
I am trying to figure out how to use a SOAP interface.
I have managed to put together a code after exploring with soapUI.
Working soapUI request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:v22="https://shop.textalk.se/webservice/v22">
<soapenv:Header/>
<soapenv:Body>
<v22:GetOrders>
<Login>
<Shop>23946</Shop>
<Username>user#mysite.com</Username>
<Password>HIDDEN</Password>
</Login>
<!--Zero or more repetitions:-->
<Orders>44753668</Orders>
<Status>All</Status>
</v22:GetOrders>
</soapenv:Body>
</soapenv:Envelope>
Non working PHP request:
<?php
$wsdl = "https://shop.textalk.se/webservice/v22/?WSDL";
$client = new SoapClient($wsdl, array(
'Shop'=>'23946',
'Username'=>'user#mysite.com',
'Password'=>'HIDDEN',
'trace'=>1,
'exceptions'=>0));
$request = array(
'GetOrdersResponse' => array(
'Orders' => '44753668',
'Status' => 'All'
),
);
$response = $client->GetOrders($request);
var_dump($response);
echo $response;
?>
Documentation is here: https://shop.textalk.se/webservice/v22/wsdldoc.php
When I run the php code absolutely nothing happens
I am not a PHP expert but have you tried the below code?
<?php
$wsdl = "https://shop.textalk.se/webservice/v22/?WSDL";
$client = new SoapClient($wsdl);
$request = array(
'Shop'=>'23946',
'Username'=>'user#mysite.com',
'Password'=>'HIDDEN',
'Orders' => '44753668',
'Status' => 'All'));
$response = $client->GetOrders($request);
var_dump($response);
echo $response;
?>
Check out this blog post for a good starting point http://www.vankouteren.eu/blog/2009/03/simple-php-soap-example/
Note: the code is untested!
I found out what was wrong. I had to pass the login values as an array, and not as separate values. That solved it. I am now getting correct data in return.
<?php
$wsdl = "https://shop.textalk.se/webservice/v22/?WSDL";
$client = new SoapClient($wsdl);
$request = array(
'Login' => array(
'Shop'=>"23946",
'Username'=>"mail#mysite.com",
'Password'=>"HIDDEN"),
'Orders' => "44753668",
'Status' => "All");
$response = $client->GetOrders($request);
var_dump($response);
echo $response;
?>
I am using PHP SoapClient in WSDL mode.
This is what the expected SOAP request should look like:
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns="http://xml.m4u.com.au/2009">
<soapenv:Header/>
<soapenv:Body>
<ns:sendMessages>
<ns:authentication>
<ns:userId>Username</ns:userId>
<ns:password>Password</ns:password>
</ns:authentication>
<ns:requestBody>
<ns:messages>
<ns:message>
<ns:recipients>
<ns:recipient>61400000001</ns:recipient>
</ns:recipients>
<ns:content>Message Content</ns:content>
</ns:message>
</ns:messages>
</ns:requestBody>
</ns:sendMessages>
</soapenv:Body>
</soapenv:Envelope>
And this is what PHP SoapClient is sending:
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://xml.m4u.com.au/2009">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns1:sendMessages>
<ns1:authentication>
<userId>Username</userId>
<password>Password</password>
</ns1:authentication>
<ns1:requestBody>
<messages>
<message>
<recipients>
<recipient>61400000001</recipient>
</recipients>
<content>Message Content</content>
</message>
</messages>
</ns1:requestBody>
</ns1:sendMessages>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
This is how I constructed the client and params:
function sendMessages($recipient, $content) {
$authenticationType = new SoapVar(array('userId' => $this->username, 'password' => $this->password), SOAP_ENC_OBJECT);
$recipientsType = new SoapVar(array('recipient' => $recipient), SOAP_ENC_OBJECT);
$messageType = new SoapVar(array('recipients' => $recipientsType, 'content' => $content), SOAP_ENC_OBJECT);
$messagesType = new SoapVar(array('message' => $messageType), SOAP_ENC_OBJECT);
$requestBodyType = new SoapVar(array('messages' => $messagesType), SOAP_ENC_OBJECT);
$params = array(
'authentication' => $authenticationType,
'requestBody' => $requestBodyType
);
try {
$this->soapClient = new SoapClient($this->wsdl, array('trace' => 1));
$this->soapClient->__setSoapHeaders(array());
return $this->soapClient->sendMessages($params);
} catch (SoapFault $fault) {
echo '<h2>Request</h2><pre>' . htmlspecialchars($this->soapClient->__getLastRequest(), ENT_QUOTES) . '</pre>';
trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR);
}
}
Why is 'ns1' present for 'authentication' and 'requestBody' but missing for their child nodes?
What am I doing wrong? The WSDL is located here => http://soap.m4u.com.au/?wsdl
Appreciate anyone who can help.
You must specify the URI of the namespace to encode the object. This will include everything necessary (including your missing namespace). The acronym of the namespace name is irrelevant.
This:
$authenticationType = new SoapVar(array('userId' => $this->username, 'password' => $this->password), SOAP_ENC_OBJECT);
should be:
$authenticationType = new SoapVar(array('userId' => $this->username, 'password' => $this->password), SOAP_ENC_OBJECT, "authentication","http://xml.m4u.com.au/2009");
The problem you're seeing with the namespace serialization comes from using soapvar without all the parameters. When it serializes the request prior to sending it assumes the namespace is already included. If, instead, you had created each as a simple array and included them in $params it would include the namespace for the internal parameters correctly. By way of demonstration:
$authenticationType = array('userId' => $this->username, 'password' => $this->password)
try using nusoap library. Below is sample code:
<?php
$wsdl = "http://soap.m4u.com.au/?wsdl";
// generate request veriables
$data = array();
$action = ""; // ws action
$param = ""; //parameters
$options = array(
'location' => 'http://soap.m4u.com.au',
'uri' => ''
);
// eof generate request veriables
//$client = new soap_client($wsdl, $options);// create soap client
$client = new nusoap_client($wsdl, 'wsdl');
$client->setCredentials($api_username, $api_password);// set crendencials
$opt = $client->call($action, $param, '', '', false, true);
print_r($opt);
?>