PHP: How to do a SOAP request from this XML? - php

Can someone help me?
I can not perform the AdvogadoRegular function in this web service.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:int="https://www5.oab.org.br/integracao/">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<token xmlns="http://CFOAB.Integracao">xxxxxxxx</token>
<wsa:To>https://www5.oab.org.br/Integracao/CNA.svc</wsa:To>
</soap:Header>
<soap:Body>
<int:AdvogadoRegular>
<!--Optional:-->
<int:cpf>99999999999</int:cpf>
</int:AdvogadoRegular>
</soap:Body>
</soap:Envelope>
I try to access from that code.
// WSDL
$client = new SoapClient('https://www5.oab.org.br/Integracao/CNA.svc?wsdl', $options = array(
'soap_version' => SOAP_1_2,
'trace'=>1,
'exceptions'=> 0
));
// NOME DA FUNÇÃO A SER EXECUTADA
$function = 'AdvogadoRegular';
// PARÂMETROS DA FUNÇÃO A SER EXECUTADA
$arguments= array('AdvogadoRegular' => array( 'cpf' => '99999999999' ));
// URL DO WEB SERVICE
$options = array('location' => 'https://www5.oab.org.br/Integracao/CNA.svc');
// HEADER
$token = array(
'token'=> 'xxxxxxxx',
'wsa:To'=>'https://www5.oab.org.br/Integracao/CNA.svc',
);
$header = new SoapHeader("http://CFOAB.Integracao",'token',$token,false);
$client->__setSoapHeaders($header);
// EXECUTA A FUNÇÃO
$result = $client->__soapCall($function, $arguments, $options);
echo $result;
I think the error happens when I try to send the header. Please help me...

first I would advise you to use a WSDL to php generator such as PackageGenerator, then regarding your header, it seems it's a WsSecurity header that you have to send, so you should try using the WsSecurity project that eases the way to add this type of header

Related

PHP SOAP Header for Authentication Issue

I have the below SOAP XML, Im trying to access the vehicle details with the soap header authentication. I have tried the below code. I think, Im missing something on this. Can u help
SOAPAction: "http://abcddetails.org/getVehicleDetails"
<?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:Header>
<UserIdentifierSoapHeaderIn xmlns="http://abcddetails.org/">
<UserName>string</UserName>
<Password>string</Password>
</UserIdentifierSoapHeaderIn>
</soap:Header>
<soap:Body>
<getVehicleDetails xmlns="http://abcddetails.org/">
<request>
<SystemCode>int</SystemCode>
<UserID>string</UserID>
<PlateInfo>
<PlateNo>long</PlateNo>
<PlateOrgNo>long</PlateOrgNo>
<PlateColorCode>int</PlateColorCode>
</PlateInfo>
<ChassisNo>string</ChassisNo>
</request>
</getVehicleDetails>
</soap:Body>
PHP code along with the SOAP Header, I have created as the below.
<?php
$wsdl = "http://abcddetails.org/InspectionServices.asmx?WSDL";
$client = new SoapClient($wsdl, array('trace'=>1)); // The trace param will show you errors stack
$auth = array(
'Username'=>'XXXXX',
'Password'=>'XXXXX',
);
$header = new SOAPHeader($wsdl, 'UserIdentifierSoapHeaderIn', $auth);
$client->__setSoapHeaders($header);
// web service input params
$request_param = array(
"SystemCode" => 4,
"UserID" => "TEST",
"ChassisNo" => '1N4AL3A9XHC214925'
);
$responce_param = null;
try
{
$responce_param = $client->getVehicleDetails($request_param);
//$responce_param = $client->call("webservice_methode_name", $request_param); // Alternative way to call soap method
}
catch (Exception $e)
{
echo "<h2>Exception Error!</h2>";
echo $e->getMessage();
}
print_r($responce_param);
?>
Can u guide if anything I have written wrong here in this.
You can use the __soapCall method like this:
$result = $client->__soapCall('webserviceMethodeName', ['parameters' => $params]);
In your case a soap action would be invoked like this:
$responce_param = $client->__soapCall('getVehicleDetails', ['parameters' => $request_param]);
Read more

Soap requests with Curl PHP

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

Interacting with a soap API without WSDL in PHP

Recently got access to a soap API for a hotel management service. They have provided documentation which shows a basic example of a request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<Auth xmlns="http://xxxx/xxxxAPI">
<FromSystemId ID="1">CompanyName</FromSystemId>
<UserName>username</UserName>
<Password>password</Password>
</Auth>
</soapenv:Header>
<soapenv:Body>
<GetRegions Timestamp="2016-04-11" Version="1.0" Lang="en"
xmlns="http://xxxx/xxxxAPI">
<Country Code="GB" />
</GetRegions>
</soapenv:Body>
</soapenv:Envelope>
They have also provided a list of functions in their documentation and the parameters required for each of the functions. But i am abit confused on how to perform a request as i have never used a soap API before. They also haven't provided a WSDL, does this matter?
Anyway, here is how i thought to try and perform a request
$soapURL = "http://xxxx/xxxxAPI" ;
$soapParameters = Array('login' => "username", 'password' => "password") ;
$soapFunction = "getRegions";
$soapFunctionParameters = Array('countrycode' => 'GB');
$soapClient = new SoapClient($soapURL, $soapParameters);
$soapResult = $soapClient->__soapCall($soapFunction,
$soapFunctionParameters) ;
if(is_array($soapResult) && isset($soapResult['someFunctionResult'])) {
// Process result.
} else {
// Unexpected result
if(function_exists("debug_message")) {
debug_message("Unexpected soapResult for {$soapFunction}: ".print_r($soapResult, TRUE)) ;
}
}
Am i going about this the right way? i am unable to test this right now as i haven't received my authentication but wanted to make a start on it now.
Any help would be great.
Here is a small example.
$opts = array(
'location' => 'http://xxxx/xxxxAPI',
'uri' => 'urn:http://test-uri/'
);
$client = new SOAPClient(null, $opts);
$headerData = array(
'FromSystemId' => 'CompanyName',
'UserName' => 'username',
'Password' => 'password',
);
// Create Soap Header.
$header = new SOAPHeader('http://xxxx/xxxxAPI', 'Auth', $headerData);
// Set the Headers of Soap Client.
$client->__setSoapHeaders($header);
$result = $client->__soapCall('getRegions', array('GB'));
// $return = $client->__soapCall('getRegions', array(new SoapParam(new SoapVar('GB', XSD_STRING), 'countryCode')));
var_dump($result);
They also haven't provided a WSDL, does this matter?
To be able to add the HEADER attributes they must be mentioned in WSDL. If they not exist in WSDL they WILL NOT appear as attributes but rather <item><key/><value/></item> elements.
Tipp: If you know how the request has to be and you have no WSDL, then try to generate the HTTP header and XML body manually and execute the request with CURL or Guzzle.
Example with Guzzle:
$soapContent = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<Auth xmlns="http://xxxx/xxxxAPI">
<FromSystemId ID="1">CompanyName</FromSystemId>
<UserName>username</UserName>
<Password>password</Password>
</Auth>
</soapenv:Header>
<soapenv:Body>
<GetRegions Timestamp="2016-04-11" Version="1.0" Lang="en"
xmlns="http://xxxx/xxxxAPI">
<Country Code="GB" />
</GetRegions>
</soapenv:Body>
</soapenv:Envelope>';
$client = new GuzzleHttp\Client([
'headers' => [ 'SOAPAction' => '"urn:http://xxxx/xxxxAPI/#getRegions"' ]
]);
$response = $client->post('http://xxxx/xxxxAPI',
['body' => $soapContent]
);
echo $response;

PHP SoapClient Body Parameters are not being sent

I am trying to make a SOAP call using the SoapClient within PHP but I am having trouble sending the body parameters. The headers are being sent over just fine and there are no errors but the body is empty.
I am not very familiar with PHP so this is new to me.
Here is my login function:
function Login($username, $password, $clientaccesskey, $useraccesskey)
{
$parameters = array(
'LogOnRequest' =>
array(
'ClientAccessKey' => $clientaccesskey,
'Password' => $password,
'UserAccessKey' => $useraccesskey,
'UserName' => $username
)
);
$headers = array();
$headers[] = new SoapHeader('http://www.w3.org/2005/08/addressing', 'Action', 'http://www.ultipro.com/dataservices/bidata/2/IBIDataService/LogOn');
$headers[] = new SoapHeader('http://www.w3.org/2005/08/addressing', 'To', 'https://service4.ultipro.com/services/BiDataService');
try
{
$soapclient = new SoapClient('https://service4.ultipro.com/services/BiDataService', array('soap_version' => SOAP_1_2, 'encoding' => 'UTF-8', 'exceptions' => TRUE, 'trace' => TRUE));
$soapclient->__setSoapHeaders($headers);
$response = $soapclient->__soapCall('LogOn', array($parameters));
echo json_encode($response);
echo htmlentities($soapclient->__getLastRequest());
}
catch(SoapFault $fault){
echo $fault->faultstring;
}
}
When I run this code it appears to be talking to the server because I am getting a response:
{"LogOnResult":{"ServiceId":null,"ClientAccessKey":null,"Token":null,"Status":"Failed","StatusMessage":"User authentication failed","InstanceKey":null}}
But this is the XML that is being sent to the service:
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://www.ultipro.com/dataservices/bidata/2" xmlns:ns2="http://www.w3.org/2005/08/addressing">
<env:Header>
<ns2:Action>http://www.ultipro.com/dataservices/bidata/2/IBIDataService/LogOn</ns2:Action>
<ns2:To>https://service4.ultipro.com/services/BiDataService</ns2:To>
</env:Header>
<env:Body>
<ns1:LogOn />
</env:Body>
</env:Envelope>
This is what the XML is SUPPOSED to look like:
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.ultipro.com/dataservices/bidata/2/IBIDataService/LogOn</a:Action>
<a:To s:mustUnderstand="1">https://servicehost/services/BiDataService</a:To>
</s:Header>
<s:Body>
<LogOn xmlns="http://www.ultipro.com/dataservices/bidata/2">
<logOnRequest xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<UserName>username</UserName>
<Password>password</Password>
<ClientAccessKey>12345</ClientAccessKey>
<UserAccessKey>01234567890</UserAccessKey>
</logOnRequest>
</LogOn>
</s:Body>
</s:Envelope>
What am I doing wrong that is causing the body parameters to not be sent in the SOAP request?
I was able to achieve it using a class, the SOAPVar and the SOAPParam classes, like this:
function Login($username, $password, $clientaccesskey, $useraccesskey)
{
// Class handler for the request
class LogOnRequest {
function __construct($usr, $pwd, $cak, $uak)
{
$this->UserName = $usr;
$this->Password = $pwd;
$this->ClientAccessKey = $cak;
$this->UserAccessKey = $uak;
}
}
// Conversion to a SOAP object
$lor = new LogOnRequest($username, $password, $clientaccesskey, $useraccesskey);
$logOnRequest = new SoapVar($lor, SOAP_ENC_OBJECT, 'LogOnRequest', 'http://soapinterop.org/xsd');
$headers = array();
$headers[] = new SoapHeader('http://www.w3.org/2005/08/addressing', 'Action', 'http://www.ultipro.com/dataservices/bidata/2/IBIDataService/LogOn');
$headers[] = new SoapHeader('http://www.w3.org/2005/08/addressing', 'To', 'https://service4.ultipro.com/services/BiDataService');
try
{
$soapclient = new SoapClient('https://service4.ultipro.com/services/BiDataService', array('soap_version' => SOAP_1_2, 'encoding' => 'UTF-8', 'exceptions' => TRUE, 'trace' => TRUE));
$soapclient->__setSoapHeaders($headers);
// Direct call to the LogOn method and SOAP parameter pass
$response = $soapclient->LogOn(new SoapParam($logOnRequest, 'logOnRequest'));
echo json_encode($response);
echo htmlentities($soapclient->__getLastRequest());
}
catch(SoapFault $fault){
echo $fault->faultstring;
}
}
Which gave me the following XML request:
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://soapinterop.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://www.ultipro.com/dataservices/bidata/2" xmlns:ns3="http://www.w3.org/2005/08/addressing">
<env:Header>
<ns3:Action>http://www.ultipro.com/dataservices/bidata/2/IBIDataService/LogOn</ns3:Action>
<ns3:To>https://service4.ultipro.com/services/BiDataService</ns3:To>
</env:Header>
<env:Body>
<ns2:LogOn xsi:type="ns1:LogOnRequest">
<UserName>u</UserName>
<Password>p</Password>
<ClientAccessKey>cak</ClientAccessKey>
<UserAccessKey>uak</UserAccessKey>
</ns2:LogOn>
</env:Body>
</env:Envelope>

SoapHeader formatting using PHP

I am using the following code to create a SOAPHEADER using PHP
// Instantiate the client.
$client = new SoapClient($wsdl_url, array('trace' => 1));
// Pass along login information
$soap_header = new SoapHeader(
$api_url,
'APICredentials',
array(
'DeveloperKey' => $developerKey,
'Password' => $password
)
);
$client->__setSoapHeaders($soap_header);
which created this
<SOAP-ENV:Header>
<ns2:APICredentials>
<item>
<key>DeveloperKey</key>
<value>********</value>
</item>
<item>
<key>Password</key>
<value>********</value>
</item>
</ns2:APICredentials>
</SOAP-ENV:Header>
How do I change the PHP code to create the following headers?
<soapenv:Header>
<web:APICredentials>
<web:DeveloperKey>...</web:DeveloperKey>
<web:Password>...</web:Password>
</web:APICredentials>
</soapenv:Header>
You can set this completely manual by using $soap_client->__setSoapHeaders($header);
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:
<?php
$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);
Source: http://php.net/manual/en/soapclient.setsoapheaders.php

Categories