SoapHeader formatting using PHP - 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

Related

Convert PHP SOAP call to Postman

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.

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;

How to construct SOAP header using SoapClient in PHP

I need to make soap calls which include headers like this:
<soap:Header>
<Agency xmlns="http://schemas.costacrociere.com/WebAffiliation">
<Code>1111</Code>
<Culture />
</Agency>
<Partner xmlns="http://schemas.costacrociere.com/WebAffiliation">
<Name>AAAA</Name>
<Password>XXXX</Password>
</Partner>
</soap:Header>
How to do that in PHP using SoapClient?
Plz help :)
I did it:
$ns="http://schemas.costacrociere.com/WebAffiliation";
//Body of the Soap Header.
$headerbody1 = array("Name" => "AAAA", "Password" => "XXXX");
$headerbody2 = array("Code" => "1111");
//Create Soap Header.
$header[] = new SOAPHeader($ns, 'Partner', $headerbody1);
$header[] = new SOAPHeader($ns, 'Agency', $headerbody2);
//set the Headers of Soap Client.
$client->__setSoapHeaders($header);

Difference between two soap requests

My SOAP Request
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://ws.dgpys.deloitte.com" xmlns:ns2="ws.apache.org/namespaces/axis2">
<env:Header>
<ns2:ServiceGroupId>
<BOGUS>urn:uuid:7C2F61BDE7CB9D9C6D1424938568724</BOGUS>
</ns2:ServiceGroupId>
</env:Header>
<env:Body>
<ns1:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ns1:getGunlukParametreRapor>
</env:Body>
</env:Envelope>
Expected SOAP Request
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.dgpys.deloitte.com">
<soap:Header>
<axis2:ServiceGroupId xmlns:axis2="http://ws.apache.org/namespaces/axis2">urn:uuid:479731898147E116AD1424691518968</axis2:ServiceGroupId>
</soap:Header>
<soap:Body>
<ws:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ws:getGunlukParametreRapor>
</soap:Body>
</soap:Envelope>
Tried with following codes:
$options = array(
'trace' => 1,
'exceptions' => 1,
'soap_version' => SOAP_1_2
);
$client = new SoapClient("http://dgpysws.pmum.gov.tr/dgpys/services/EVDServis.wsdl", $options);
$p1 = new stdCLass();
$p1->loginMessage = new stdCLass();
$p1->loginMessage->UserName = new stdCLass();
$p1->loginMessage->UserName->v = "Username";
$p1->loginMessage->Password = new stdCLass();
$p1->loginMessage->Password->v = "Passwor";
$client->login($p1);
$headers[] = new SoapHeader('http//ws.apache.org/namespaces/axis2', 'ServiceGroupId', "UNIQUEID", false);
$client->__setSoapHeaders($headers);
$result = $client->getGunlukParametreRapor(array('date' => '2015-02-22T00:00Z'));
Question is:
These SOAP requests are same?
I'm using SOAP_1_2 and it should be like Expected SOAP Request but my request doesnt looks like to expected format. Missing where?
How can i get the output like as expected?
Note: dgpysws.pmum.gov.tr wsdl address is private area.
They are not the same. To get rid of the BOGUS node you need to use this:
$strHeaderComponent_Session = "<SessionHeader><ServiceGroupId>$theVarWithTheIDGoesHere</ServiceGroupId></SessionHeader>";
$objVar_Session_Inside = new SoapVar($strHeaderComponent_Session, XSD_ANYXML,
null, null, null);
$objHeader_Session_Outside = new SoapHeader('http//ws.apache.org/namespaces/axis2',
'SessionHeader', $objVar_Session_Inside);
// More than one header can be provided in this array.
$client->__setSoapHeaders(array($objHeader_Session_Outside));
try the following
$ns = 'http//ws.apache.org/namespaces/axis2'; //Namespace of the WS.
//Body of the Soap Header.
$headerbody = array('ServiceGroupId' => $UNIQUEID_Token);
//Create Soap Header.
$header = new SOAPHeader($ns, 'axis2', $headerbody);
//set the Headers of Soap Client.
$soap_client->__setSoapHeaders($header);
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://ws.dgpys.deloitte.com" xmlns:ns2="ws.apache.org/namespaces/axis2">
<env:Header>
<ns2:ServiceGroupId>
urn:uuid:7C2F61BDE7CB9D9C6D1424938568724
</ns2:ServiceGroupId>
</env:Header>
<env:Body>
<ns1:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ns1:getGunlukParametreRapor>
</env:Body>
</env:Envelope>
And
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:ws="http://ws.dgpys.deloitte.com">
<soap:Header>
<axis2:ServiceGroupId xmlns:axis2="http://ws.apache.org/namespaces/axis2">urn:uuid:479731898147E116AD1424691518968</axis2:ServiceGroupId>
</soap:Header>
<soap:Body>
<ws:getGunlukParametreRapor>
<date>2015-02-22T00:00Z</date>
</ws:getGunlukParametreRapor>
</soap:Body>
</soap:Envelope>
Are the same.
env=soap, ns2=ws and ns2=axis2. You can have any prefix to refer to these namespaces as you like. Once you assign the prefix you just refer to it using that in the other places. Only diff was the bogus tag tin first request. Just remove that.

Create this SOAP XML request with PHP's SOAP extension

I'm trying to recreate this XML request using PHP's SOAP extension and having trouble doing it:
<?xml version="1.0"?>
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.web.stormpost.skylist.com">
<soapenv:Header>
<authInfo xmlns:soap="http://skylist.com/services/SoapRequestProcessor" xsi:type="soap:authentication">
<!--You may enter the following 2 items in any order-->
<username xsi:type="xsd:string">****#example.com</username>
<password xsi:type="xsd:string">*******</password>
</authInfo>
</soapenv:Header>
<soapenv:Body>
<ser:doImportFromTemplate soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<impTempId xsi:type="xsd:int">7</impTempId>
<data xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="soapenc:string">
Joe|Doe|joe#example.com John|Doe|john#example.com </data>
</ser:doImportFromTemplate>
</soapenv:Body>
</soapenv:Envelope>
Here is my testing code so far:
// set connection params
$wsdl = 'http://api.stormpost.datranmedia.com/services/SoapRequestProcessor?wsdl';
$namespace = 'https://api.stormpost.datranmedia.com/services/SoapRequestProcessor';
$credentials = (object)array(
'username' => '****#example.com',
'password' => '*******'
);
$auth_values = new SoapVar($credentials, SOAP_ENC_OBJECT);
$header = new SoapHeader($namespace, "authInfo", $auth_values);
// set client, headers, and call function
$client = new SoapClient($wsdl, array('trace' => true));
$client->__setSoapHeaders(array($header));
$client->__soapCall("doImportFromTemplate", array(7, 'Joe|Doe|joe#example.com John|Doe|john#example.com'));
It doesn't seem to be implementing the authInfo node correctly with the xsi:type="soap:authentication" among other things. How should I change my code to output this XML? I'm having trouble finding good implementation examples.
I struggled with the php SOAP client myself a while ago, i didn't really got a full understanding but this worked for me:
$auth_values = array('username' => '****#example.com', 'password' => '*******');
$header = new SoapHeader($namespace, "authInfo", $auth_values, false);
// set client, headers, and call function
$client = new SoapClient($wsdl, array('trace' => true));
$client->__setSoapHeaders(array($header));

Categories