I'm trying to make a SOAP request using PHP and I don't seem to be able to seperate my parameters I need to send with the call. I can use the service through out a SOAP testing tool, and the snippet I'm using there is (with ccn3 and ccn2 removed):
<?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>
<tns:GetUser>
<tns:auth>
<ccn3:Username>testuser</ccn3:Username>
<ccn3:Password>testpass</ccn3:Password>
<ccn3:AuthID>55125621</ccn3:AuthID>
</tns:auth>
<tns:user>
<ccn2:Address>Testvägen 1</ccn2:Address>
<ccn2:CustNo/>
<ccn2:FirstName/>
<ccn2:LastName/>
<ccn2:SSN>1234567890</ccn2:SSN>
</tns:user>
</tns:GetUser>
</soap:Body>
</soap:Envelope>
This do work and gives the desired answer from the service. But when connecting to it through php it doesn't. The php code I'm currently using looks like this:
<?php
$username = "testuser";
$password = "testpass";
$authID = 55125621;
$client = new SoapClient("https://url/service.svc?wsdl");
$param = array(
'Username'=>$username,
'Password'=>$password,
'AuthID'=>$AuthID,
'Address'=>'Testvägen 1',
'SSN'=>'1234567890',
'FistName'=>'',
'LastName'=>''
);
$res = $client->GetUser($param);
echo "<pre>";
print_r($res);
echo "</pre>";
?>
In my XML query I'm using two "groups" of parameters. I send auth data towards my ccn3 (tns:auth) and my data to ccn2 (tns:user). I'm guessing that's my problem, but how do I do this seperation in php?
Try this:
$params = array(
'auth' => array(
'Username' => $username,
'Password' => $password,
'AuthID' => $AuthID,
),
'user' => array(
'Address' => 'Testvägen 1',
'SSN' => '1234567890',
'FistName' => '',
'LastName' => ''
));
$res = $client->GetUser($params);
Related
I am creating an SOAP client using PHP and having issues with consuming. When I test the request direct XML using soapui it responds fine and works but with PHP using SoapClient class it tells me the same credentials which I use in soapui are incorrect.
Not sure what I am missing here. My code below
Below is my XML
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:pric="http://upshot.co.uk/pricing_request_ws">
<soapenv:Header/>
<soapenv:Body>
<pric:retrieveProductsPricing>
<username>apiuser</username>
<password>pword</password>
<postcode>EC2R 7HP</postcode>
</pric:retrieveProductsPricing>
</soapenv:Body>
</soapenv:Envelope>
Below is my PHP
$wsdl = "http://URL?wsdl";
$client = new SoapClient($wsdl, array('trace'=>1));
try
{
$options = array(
'soap_version'=>SOAP_1_2,
'exceptions'=>true,
'trace'=>1,
'cache_wsdl'=>WSDL_CACHE_NONE
);
$params = array(
'User name' => 'apiuser',
'Password' => 'pword',
'Postcode' => 'EC2R 7HP'
);
$response = $client->retrieveProductsPricing($params);
print_r($response);
}
catch(SoapFault $e)
{
print_r($e);
This is my first time configuring a soap client so I'm sure I have potentially made a mistake in this.
Have a look at the first code:
<username>apiuser</username>
<password>pword</password>
<postcode>EC2R 7HP</postcode>
You should use the same keys for the array
$params = array(
'username' => 'apiuser',
'password' => 'pword',
'postcode' => 'EC2R 7HP'
);
Useful examples
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 am pulling my hair out. I have tried many different ways, but nothing works:
<?php
// Proxy is for Fiddler
$soap = new soapClient( 'http://testi.lemonsoft.eu:22000/CTP/lemonweb/userservices.svc?wsdl', array(
'proxy_host' => 'localhost',
'proxy_port' => '8888'
));
try {
$test = new stdClass();
$test->UserName = "foo";
$test->Password = "bar";
$test->CompanyDatabase = "baz";
// This should work:
print_r($soap->LogIn($test));
/** The rest are alternative experiments, no avail: **/
print_r($soap->LogIn(array($test)));
print_r($soap->LogIn(array('parameters' => $test)));
print_r($soap->login(array(
'UserName' => 'foo',
'Password' =>'bar',
'CompanyDatabase' => 'baz'
)));
print_r($soap->__soapCall('LogIn', array('parameters' => $test)));
print_r($soap->__soapCall('LogIn', array('parameters' => array(
'UserName' => 'foo',
'Password' =>'bar',
'CompanyDatabase' => 'baz'
))));
print_r($soap->LogIn(new SoapParam($test, "LogIn")));
print_r($soap->LogIn(new SoapParam(array(
'UserName' => 'foo',
'Password' =>'bar',
'CompanyDatabase' => 'baz'
), "LogIn")));
print_r($soap->__soapCall('LogIn', array('parameters' => array(
new SoapParam(array(
'UserName' => 'foo',
'Password' =>'bar',
'CompanyDatabase' => 'baz'
), "LogIn")
))));
} catch (SoapFault $fault) {
print_r($fault);
}
?>
I captured the requests with fiddler and the response always looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/">
<SOAP-ENV:Body>
<ns1:LogIn/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
as if the LogIn parameters are never sent. Does the empty ns1:LogIn tag really mean that? Can there be some instance inbetween, which I can not control, for some reason stripping the parameters? According to my understanding the method LogIn takes one parameter, which, according to the documentation, should be a PHP stdClass.
Try this:
class LogInInfo{
public $UserName = '1';
public $Password = '2';
public $CompanyDatabase = '3';
}
ini_set('display_error', 1);
error_reporting(E_ALL);
$client = new SoapClient('http://testi.lemonsoft.eu:22000/CTP/LemonWeb/UserServices.svc?singleWsdl', array(
'classmap'=>array('LogInInfo'=>'LogInInfo'),
'debug'=>true,
'trace'=>true
));
try {
$info = new LogInInfo();
$resp = $client->LogIn($info);
} catch(Exception $e) {
var_dump($e);
}
print_r($client->__getLastRequest());
Result:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schemas.datacontract.org/2004/07/Lemonsoft.LemonsoftServiceLibrary.User" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://tempuri.org/">
<SOAP-ENV:Body>
<ns2:LogIn xsi:type="ns1:LogInInfo">
<ns1:CompanyDatabase>3</ns1:CompanyDatabase>
<ns1:Password>2</ns1:Password>
<ns1:UserName>1</ns1:UserName>
</ns2:LogIn>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Can you show content of the WSDL file?
ns1:LogIn tag means that method LogIn is from ns1 namespace (defined above).
The only way I manage to pass the params in SOAP request from PHP is like this:
// __setSoapHeaders here
$listCriteriaXML = '<List xmlns="LINKHERE">
<listCriteria>
<ListCriterion>
<Name>DateNeeded</Name>
<SingleValue>' . date("Y-m-d", strtotime("+120 days")) . '</SingleValue>
</ListCriterion>
<ListCriterion>
<Name>limitresults</Name>
<SingleValue>false</SingleValue>
</ListCriterion>
</listCriteria>
</List>';
$listCriteria = new SoapVar($listCriteriaXML, XSD_ANYXML);
$response = $client->List($listCriteria);
echo $client->__getLastRequest();
I have looked all over stack overflow and only found a couple threads related but they did not solve my problem. Also, for what it's worth, this is an LTL carrier by the name of Estes that I am trying to get this to work through.
Here's the code I'm using:
$url = "http://www.estes-express.com/rating/ratequote/services/RateQuoteService?wsdl";
$username = 'un';
$password = 'pw';
$client = new SoapClient($url);
//Prepare SoapHeader parameters
$cred = array(
'user' => $username,
'password' => $password
);
$headers = new SoapHeader('http://ws.estesexpress.com/ratequote', 'auth', $cred);
$client->__setSoapHeaders($header);
$params = array(
"requestID" => "20131724",
"account" => "9252066",
"originPoint" => array('countryCode' => 'US', 'postalCode' => "43537"),
"destinationPoint" => array('countryCode' => 'US', 'postalCode' => "43460"),
"payor" => 'S',
"terms" => 'PPD',
"stackable" => 'N',
"baseCommodities" => array('commodity' => array('class' => "55", 'weight' => "500") )
);
$return = $client->getQuote(array("rateRequest"=>$params));
return $return;
Here is the response I am getting:
[Client] SOAP-ERROR: Encoding: object has no 'requestID' property
Any help on this would be great!
PS. I have already tried putting them in stdClass() objects with not result. Also, their WSDL is in the code if you want to check it out.
EDITED:
Here is a dump of what the request should look like:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:rat="http://ws.estesexpress.com/ratequote" xmlns:rat1="http://ws.estesexpress.com/schema/2012/12/ratequote">
<soapenv:Header>
<rat:auth>
<rat:user>xxxxx</rat:user>
<rat:password>xxxxxx</rat:password>
</rat:auth>
</soapenv:Header>
<soapenv:Body>
<rat1:rateRequest>
<rat1:requestID>20131724</rat1:requestID>
<rat1:account>9252066</rat1:account>
<rat1:originPoint>
<rat1:countryCode>US</rat1:countryCode>
<rat1:postalCode>43537</rat1:postalCode>
<!--Optional:-->
<rat1:city>Maumee</rat1:city>
<!--Optional:-->
<rat1:stateProvince>OH</rat1:stateProvince>
</rat1:originPoint>
<rat1:destinationPoint>
<rat1:countryCode>US</rat1:countryCode>
<rat1:postalCode>23237</rat1:postalCode>
<rat1:stateProvince>VA</rat1:stateProvince>
</rat1:destinationPoint>
<rat1:payor>S</rat1:payor>
<rat1:terms>PPD</rat1:terms>
<rat1:stackable>N</rat1:stackable>
<rat1:baseCommodities>
<!--1 to 99 repetitions:-->
<rat1:commodity>
<rat1:class>50</rat1:class>
<rat1:weight>100</rat1:weight>
</rat1:commodity>
</rat1:baseCommodities>
</rat1:rateRequest>
</soapenv:Body>
</soapenv:Envelope>
This caught me out the other day, too: the parameters expected by the SoapClients called should not include the outermost XML tag within the body, in this case rateRequest, as this is generated automatically based on the description in the WSDL. Instead, you need to pass a structure (array or object) containing each of the parameters defined within that outer tag.
So in your case, you just need to change this:
$return = $client->getQuote(array("rateRequest"=>$params));
to this:
$return = $client->getQuote($params);
Incidentally, your code as pasted also has a typo where you define $headers but then reference $header. A live demo with both changes shows instead a "User authentication failed." fault (presumably because you were wise enough not to give us your real login details!)
In case anyone is still having trouble with this, in order to get this to work I had to change the $params into an object or else I would receive an error, "Object Property Does Not Exist"
$params = new stdClass();
$params->requestID = "20131724";
$params->account = "123456";
$params->originPoint = array('countryCode' => 'US', 'postalCode' => "43537");
$params->destinationPoint = array('countryCode' => 'US', 'postalCode' => "43460");
$params->payor = "S";
$params->terms = "PPD";
$params->stackable = "N";
$params->baseCommodities = array('commodity' => array('class' => "55", 'weight' => "100") );
$return = $client->getQuote($params);
I never worked with SOAP XML api before.
I read a couple of similar questions on SO but I can't get it to work.
Here's a simple request:
<soap12:Envelope xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:xsd=”http://www.w3.org/2001/XMLSchema” xmlns:soap12=”http://www.w3.org/2003/05/
soap-envelope”>
<soap12:Body>
<CheckDomainAvailability xmlns=”https://live.domainbox.net/”>
<AuthenticationParameters>
<Reseller>myreseller</Reseller>
<Username>myuser</Username>
<Password>mypassword</Password>
</AuthenticationParameters>
<CommandParameters>
<DomainName>checkadomain.co</DomainName>
<LaunchPhase>GA</LaunchPhase>
</CommandParameters>
</CheckDomainAvailability>
</soap12:Body>
</soap12:Envelope>
I've contacted them but they do not offer a PHP API.
I would like to use the SoapClient class built in PHP.
The question is:
How do I send the request and print the answer?
Looks like your WSDL is located at https://live.domainbox.net/?WSDL.
Here's an example using the native PHP SoapClient.
$client = new SoapClient('https://live.domainbox.net/?WSDL');
// populate the inputs....
$params = array(
'AuthenticationParameters' => array(
'Reseller' => '',
'Username' => '',
'Password' => ''
),
'CommandParameters' => array(
'DomainName' => '',
'LaunchPhase' => ''
)
);
$result = $client->CheckDomainAvailability($params);
print_r($result);
To get this working I needed to change the first line to get the right version of soap to 1.2.
Also a previous comment
$client = new SoapClient('https://live.domainbox.net/?WSDL', array('soap_version' => SOAP_1_2));
// populate the inputs....
$params = array(
'AuthenticationParameters' => array(
'Reseller' => '',
'Username' => '',
'Password' => ''
),
'CommandParameters' => array(
'DomainName' => '',
'LaunchPhase' => ''
)
);
$result = $client->CheckDomainAvailability($params);
print_r($result);