I am trying to send a SOAP request with a header and lots of parameters. This is not the first time I have used NuSOAP and have never had problems with it before. However what is new to me is I am including a header which may be what is causing the problem. Below is the code for my request:
$client = new nusoap_client($url,'wsdl','','','','');
$header =
"<ETGHeader>
<VersionRequest>1.0.0</VersionRequest>
<Originator>
<Signature>Signature</Signature>
<LoginData>
<Name>Name</Name>
<Password>Password</Password>
</LoginData>
</Originator>
</ETGHeader>";
$client->setHeaders($header);
$param = array(
"Settings" => array(
"param1" => "1",
"param2" => "2",
"param3" => "3"
)
);
// Call the WebService
$result = $client->call('GetListVehicleType', array('parameters' => $param), '', '', false, true);
echo '<pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
Here is the request that is being sent:
<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope 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:Header><ETGHeader>
<VersionRequest>1.0.0</VersionRequest>
<Originator>
<Signature>Signature</Signature>
<LoginData>
<Name>Name</Name>
<Password>Password</Password>
</LoginData>
</Originator>
</ETGHeader></SOAP-ENV:Header><SOAP-ENV:Body><GetListVehicleType xmlns="http://url"/></SOAP-ENV:Body></SOAP-ENV:Envelope>
None of my parameters are being included in the request.
Any help much appreciated
Alex
Might be a problem with NuSOAP, recoded it using PHP's inbuilt SoapClient and got it working.
Related
I am trying to make a SOAP call using POSTMAN that will duplicate a call I'm making with a PHP code for testing purposes, but I am getting a "Bad request" error message, so I assume my conversion is incorrect.
The PHP code is:
//Create xml string
$xml=new DomDocument();
$xml->createCDATASection('![CDATA[]]');
$xml->encoding = 'utf-8';
$xml->xmlVersion = '1.0';
$xml->formatOutput = true;
$xsd=$xml->createElement("xsd:schema");
$xml->appendChild($xsd);
$xsdattr=new DOMAttr("xmlns:xsd","http://www.w3.org/2001/XMLSchema");
$xsd->setAttributeNode($xsdattr);
$ZHT=$xml->createElement("ZHT",str_replace(" ","",$username));
$xsd->appendChild($ZHT);
$PASSWORD=$xml->createElement("PASSWORD",str_replace(" ","",$pwd));
$xsd->appendChild($PASSWORD);
$SNL=$xml->createElement("SNL",$date);
$xsd->appendChild($SNL);
$USERNAME=$xml->createElement("USERNAME","");
$xsd->appendChild($USERNAME);
$RETHASIMA=$xml->createElement("RETHASIMA","1");
$xsd->appendChild($RETHASIMA);
$LANG=$xml->createElement("LANG","");
$xsd->appendChild($LANG);
$ROLE=$xml->createElement("ROLE",$role);
$xsd->appendChild($ROLE);
$xmlstring=$xml->saveXML();
//Set SOAP request
$baseURL=$url;
$arrContextOptions=array("ssl"=>array( "verify_peer"=>false, "verify_peer_name"=>false,'crypto_method' => STREAM_CRYPTO_METHOD_TLS_CLIENT));
$options = array(
'soap_version' => SOAP_1_1,
'trace' => true,
'exceptions' => true, // disable exceptions
'features' => SOAP_SINGLE_ELEMENT_ARRAYS,
'encoding' => 'UTF-8',
'cache_wsdl'=>WSDL_CACHE_NONE,
);
$client = new SoapClient($baseURL."?wsdl", $options);
$p=array(
"P_RequestParams" => array (
"RequestID"=>"48",
"InputData"=>$xmlstring
) ,
"Authenticator" => array (
"Password"=>$authpass,
"UserName"=>$authuser
),
);
//SOAP call and response
$response=$client->ProcessRequestJSON($p);
And This is the body I created in POSTMAN:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ProcessRequestJSON xmlns="****">
<P_RequestParams>
<RequestID>48</RequestID>
<InputData>
<?xml version="1.0" encoding="utf-8" ?>
<schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PARAMS>
<ZHT>****</ZHT>
<PASSWORD>****</PASSWORD>
<SNL>***</SNL>
<USERNAME></USERNAME>
<RETHASIMA>1</RETHASIMA>
<LANG></LANG>
<ROLE>1</ROLE>
</PARAMS>
</schema>
</InputData>
</P_RequestParams>
<Authenticator>
<UserName>****</UserName>
<Password>****</Password>
</Authenticator>
</ProcessRequestJSON>
</soap:Body>
</soap:Envelope>
I'm not sure how to set certain things on POSTMAN.
For example, the following line:
$xsdattr=new DOMAttr("xmlns:xsd","http://www.w3.org/2001/XMLSchema");
How do I set a DOMAttr in POSTMAN?
Or the options?
I set up the headers for XML:
Content-Type: text/xml
SOAPAction: "****/ProcessRequestJSON"
Body: Raw (XML)
I tried putting the inner XML (inside the tag) in "" to indicate a string, but that didn't work either.
The PHP code works correctly, the SOAP call is successful and returns a correct response.
The POSTMAN request returns a "Bad Request" error message.
How can I make Soap request using Curl php by using below soap format and url? I have tried avaliable solutions online and none of them worked out.
$soap_request = '<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:alisonwsdl" 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:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Header>
<credentials>
<alisonOrgId>9ReXlYlpOThe24AWisE</alisonOrgId>
<alisonOrgKey>C2owrOtRegikaroXaji</alisonOrgKey>
</credentials>
</soap:Header>
<SOAP-ENV:Body>
<q1:login xmlns:q1="urn:alisonwsdl">
<email xsi:type="xsd:string">email</email>
<firstname xsi:type="xsd:string">fname</firstname>
<lastname xsi:type="xsd:string">lname</lastname>
<city xsi:type="xsd:string">city</city>
<country xsi:type="xsd:string">country</country>
<external_id xsi:type="xsd:string"></external_id>
</q1:login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
Url
https://alison.com/api/service.php?wsdl
Assuming you already have php_soap extension installed, you can access the SOAP API like this:
<?php
$client = new SoapClient('https://alison.com/api/service.php?wsdl', array(
'stream_context' => stream_context_create(array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
))
));
You might want to define the header for authentication as well
$auth = array(
'alisonOrgId' => '9ReXlYlpOThe24AWisE',
'alisonOrgKey' => 'C2owrOtRegikaroXaji'
);
$header = new SoapHeader('https://alison.com/api/service.php?wsdl', 'credentials', $auth, false);
$client->__setSoapHeaders($header);
Then you can get the list of functions available
// Get function list
$functions = $client->__getFunctions ();
echo "<pre>";
var_dump ($functions);
echo "</pre>";
die;
Or call a function right away, like this:
// Run the function
$obj = $client->__soapCall("emailExists", array(
"email" => "test#email.com"
));
echo "<pre>";
var_dump ($obj);
echo "</pre>";
die;
After struggling for a week I was able to find something in this tutorial here on youtube https://www.youtube.com/watch?v=6V_myufS89A and I was able to send requests to the API successifuly, first read my xml format above before continuing with my solution
$options = array('trace'=> true, "exception" => 0);
$client = new \SoapClient('your url to wsdl',$options);
//if you have Authorization parameters in your xml like mine above use SoapVar and SoapHeader as me below
$params = new \stdClass();
$params->alisonOrgId = 'value here';
$params->alisonOrgKey = 'value here';
$authentication_parameters = new \SoapVar($params,SOAP_ENC_OBJECT);
$header = new \SoapHeader('your url to wsdl','credentials',$authentication_parameters);
$client->__setSoapHeaders(array($header));
print_r($client->__soapCall("Function here",'Function parameter here or left it as null if has no parameter'));
//or call your function by
print_r($client->yourFunction($function_parameters));
}
Hope this will help someone out there struggling with soap requests that contains authentication informations
I'm trying to send user registrations with soap to another server. I'm creating an xml with DOMdocument and than after saveXML I'm running the soap which should return an xml with registration id plus all the data I sent in my xml.
But the Soap returns unknown error. exactly this: stdClass Object ( [RegisztracioInsResult] => stdClass Object ( [any] => 5Unknown error ) )
and this is how I send my xml.
/*xml creation with DOMdocument*/
$xml = saveXML();
$url = 'http://mx.biopont.com/services/Vision.asmx?wsdl';
$trace = '1';
$client = new SoapClient($url, array('trace' => $trace, "exceptions" => 0, 'features' => SOAP_SINGLE_ELEMENT_ARRAYS));
$params = $client->RegisztracioIns(array('xml' => $xml));
$print_r($params);
If I click on the description of the RegisztracioIns service at this URL http://mx.biopont.com/services/Vision.asmx it shows me this:
POST /services/Vision.asmx HTTP/1.1
Host: mx.biopont.com
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://mx.biopont.com/services/RegisztracioIns"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<RegisztracioIns xmlns="http://mx.biopont.com/services/">
<xml>string</xml>
</RegisztracioIns>
</soap:Body>
</soap:Envelope>
According to this I think I'm doing the upload correctly but maybe not I don't have much experience with soap.
Is there anything I'm missing? I also tried to save the xml to my server an than get the contents with file_get_contents(). but the result was the same.
You should be able to do something like this:
$res = $client->__soapCall( 'RegisztracioIns', array('xml'=>'my string to send'));
To have the wsdl wrap 'my string to send' in the proper tags.
You are doing something similar, but I dont think the wsdl is actually wrapping the string you are trying to pass, and passing nothing instead, resulting in unknown error.
You can examine the outgoing xml using $client->__getLastRequest();.
(Also, you have a small typo in your code on the last line should be print_r($params);.)
Failing that you could try to write the xml yourself using SoapVar() and setting the type to XSD_ANYXML.
It seems cleaner to me when the wsdl wraps everything for you, but its better than banging your head against the wall until it does.
I made an attempt to do just that with your wsdl. Give this a try:
$wsdl = "http://mx.biopont.com/services/Vision.asmx?wsdl";
$client = new SoapClient($wsdl, array( 'soap_version' => SOAP_1_1,
'trace' => true,
));
try {
$xml = "<RegisztracioIns xmlns='http://mx.biopont.com/services/'>
<xml>string</xml>
</RegisztracioIns>";
$args= array(new SoapVar($xml, XSD_ANYXML));
$res = $client->__soapCall( 'RegisztracioIns', $args );
var_dump($res);
} catch (SoapFault $e) {
echo "Error: {$e}";
}
print_r($client->__getLastRequest());
print_r($client->__getLastResponse());
I can't exactly read the response I am getting with that given that it is Hungarian (I think?). So let me know if that works for you.
I am using a non-wsdl soap call to a web service and I am able to build the request how I need however I need to set a schema Version within the envelope body.
I am able to build this request with the PHP SoapClient:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://schemas.discovery.co.za/vitality">
<env:Body>
<ns1:UsageEligibilityRequest>
<ns1:RequestingEntityNumber>12345678</ns1:RequestingEntityNumber>
<ns1:Entities>
<ns1:EntityNumber>12345678</ns1:EntityNumber>
<ns1:DateOfBirth>1980-01-01</ns1:DateOfBirth>
<ns1:Gender>M</ns1:Gender>
<ns1:FirstInitial>H</ns1:FirstInitial>
</ns1:Entities>
</ns1:UsageEligibilityRequest>
</env:Body>
</env:Envelope>
However I need this line:
<ns1:UsageEligibilityRequest>
to be
<ns1:UsageEligibilityRequest schemaVersion="1.0">
Not sure how to do this in PHP using the built in functions/options and appears to be hard to Google.
This is built using code like:
$client->__soapCall('UsageEligibilityRequest', array($options));
Thanks.
There's 2 ways you can do this
$requestingUser = 12345678;
$entityNumber = 12345678;
$dateOfBirth = '1980-01-01';
$gender = 'M';
$firstInitial = 'H';
Either use a SoapVar like:
$paramsSOAPVar = new SoapVar('<ns1:UsageEligibilityRequest schemaVersion="1">
<ns1:RequestingEntityNumber>' . $requestingUser. '</ns1:RequestingEntityNumber>
<ns1:Entities>
<ns1:EntityNumber>' . $entityNumber. '</ns1:EntityNumber>
<ns1:DateOfBirth>' .$requestingUser. '</ns1:DateOfBirth>
<ns1:Gender>' .$gender. 'M</ns1:Gender>
<ns1:FirstInitial>' .$firstInitial. '</ns1:FirstInitial>
</ns1:Entities>
</ns1:UsageEligibilityRequest>', XSD_ANYXML);
Set up your array of parameters:
$params = array(
'schemaVersion' => 1,
'RequestingEntityNumber' => $requestingUser,
'Entities' => array(
'EntityNumber' => $entityNumber,
'DateOfBirth' => $dateOfBirth,
'Gender' => $gender,
'FirstInitial' => $firstInitial
)
);
I'm trying to login to an API using built-in soap functions of PHP. I got a result like this.
[LoginResult]=> false,
[ErrorMsg] => Login failed with the reason : The security object is invalid
This is what required by the API provider.
<?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>
<Login xmlns="http://tempuri.org/Example/Service1">
<objSecurity>
<WebProviderLoginId>test</WebProviderLoginId>
<WebProviderPassword>test</WebProviderPassword>
<IsAgent>false</IsAgent>
</objSecurity>
<OutPut />
<ErrorMsg />
</Login>
</soap:Body>
</soap:Envelope>
&, here is what I was able to produce using functions.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/Example/Service1">
<SOAP-ENV:Body>
<ns1:Login>
<objSecurity>
<WebProviderLoginId>test</WebProviderLoginId>
<WebProviderPassword>test</WebProviderPassword>
<IsAgent>false</IsAgent>
</objSecurity>
<OutPut/>
<ErrorMsg/>
</ns1:Login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Here is the code I used to send the request.
<?php
class objSecurity {
function objSecurity($s, $i, $f) {
$this->WebProviderLoginId = $s;
$this->WebProviderPassword = $i;
$this->IsAgent = $f;
}
}
class nextObject {
function nextObject($objSecurity) {
$this->objSecurity=$pobjSecurity;
$this->OutPut=NULL;
$this->ErrorMsg=NULL;
}
}
$url = 'http://example.com/sampleapi/test.asmx?WSDL';
$client = new SoapClient($url, array("soap_version" => SOAP_1_1,"trace" => 1));
$struct = new objSecurity('test', 'test', false);
$data = new nextObject($struct);
$soapstruct2 = new SoapVar($data, SOAP_ENC_OBJECT);
print_r(
$client->__soapCall(
"Login",
array(new SoapParam($soapstruct2, "inputStruct"))
)
);
echo $client->__getLastRequest();
?>
These are the differences I found.
In my request xmlns:xsi is missing.
Requirement starts with <soap:Envelope, But my request starts with <SOAP-ENV:Envelope.
There is an extra xmlns:ns1 in my request.
& The function name tag starts with ns1:.
Please help me to make my request into the required format.
I don't know much about the SOAP and I'm using PHP version 5.3.13 with CakePHP 2.3.0. Sorry, for my bad English.
Here is the solution. :)
<?php
$url = 'http://example.com/sampleapi/test.asmx?WSDL';
$client = new SoapClient($url, array("soap_version" => SOAP_1_1,"trace" => 1));
$user_param = array (
'WebProviderLoginId' => "test",
'WebProviderPassword' => "test",
'IsAgent' => false
);
$service_param = array (
'objSecurity' => $user_param,
"OutPut" => NULL,
"ErrorMsg" => NULL
);
print_r(
$client->__soapCall(
"Login",
array($service_param)
)
);
echo $client->__getLastRequest();
?>
& the request was:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://tempuri.org/Example/Service1">
<SOAP-ENV:Body>
<ns1:Login>
<ns1:objSecurity>
<ns1:WebProviderLoginId>test</ns1:WebProviderLoginId>
<ns1:WebProviderPassword>test</ns1:WebProviderPassword>
<ns1:IsAgent>false</ns1:IsAgent>
</ns1:objSecurity>
</ns1:Login>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Thanks to this link.
PHP SOAP Request not right