PHP SoapClient - action in the wrong place - php

I'm using PHP SoapClient, and am running into an issue with getting the request format just as a third party wants it.
They want it like this:
POST /service.asmx HTTP/1.1
Host: service.com
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<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>
<Order xmlns="http://someservice">
<json>string</json>
</Order>
</soap12:Body>
</soap12:Envelope>
However, the closest I can seem to get it, using SoapClient, is like this:
POST /service.asmx HTTP/1.1
Host: service.com
Content-Type: application/soap+xml; charset=utf-8; action="http://someservice"
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<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>
<Order>
<json>string</json>
</Order>
</soap12:Body>
</soap12:Envelope>
Notice how the action in my request is in the http header, and the action in their ideal format is in the Order tag. The thing is, it's SoapClient that is generating where that action is being placed - it gets that specific url from the WSDL, it's not even in my code.
How do I tell SoapClient to put it in the right spot? For my part, trying to only include what's necessary, this is essentially the code:
$this->client = new SoapClient($this->wsdl, array(
'soap_version' => SOAP_1_2,
'encoding' => 'UTF-8',
'stream_context' => stream_context_create($context),
'trace' => true,
'exceptions' => true,
)
);
$json = json_encode($request);
// Prepare the xml
$xml = array();
$xml[] = new SoapVar($json, XSD_STRING, 'string', 'http://www.w3.org/2001/XMLSchema', 'json');
$this->finalXML = new SoapVar($xml, SOAP_ENC_OBJECT, null, null, 'Order');
$this->response = $this->client->CreateOrder($this->finalXML);

After days of banging my head, I found this and ended up making the accepted, hacky solution work for me:
Change SOAP request format
Apparently, when you're working with a poorly written Soap API, there's not a lot you can do.

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.

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.

Connect to sample SOAP 1.1 with PHP

Hello i need to connect to SOAP web services with password, username and SourceId in php.
the SOAP request is:
POST /webservices/AgentOnlineReservation.asmx HTTP/1.1
Host: 54.228.189.53
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/GetHotelsData"
<?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>
<GetHotelsData xmlns="http://tempuri.org/">
<SourceId>string</SourceId>
<UserName>string</UserName>
<Password>string</Password>
</GetHotelsData>
</soap:Body>
</soap:Envelope>
Please help me.
Use the native SoapClient library:
$client = new SoapClient('linkhere.com/AgentOnlineReservation.asmx?wsdl');
$response = $client->GetHotelsData(array(
'SourceId' => '...',
'UserName' => '...',
'Password' => '...'
));
print_r($response);
The link passed in the SoapClient call is the WSDL (Web Service Description Language) file.

Consume a .Net web service using PHP

This is my first time with web services/SOAP...i have been trying to consume .Net web services using PHP but to no avail. I have searched and read all pages that google throws up for anything related to this but i am still lost.
The thing is the SOAP service i am trying to call has an authorization header and i can't figure out a way to authenticate my request.
I have tried the php-soapclient and NuSoap both but there is no sample code available that would help. So any help would be great.
The following is a sample SOAP 1.1 request and response.
POST /OxiWalletService/Service.asmx HTTP/1.1
Host: 172.160.0.49
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://tempuri.org/WS_GetData"
<?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>
<AuthHeader xmlns="http://tempuri.org/">
<UserName>string</UserName>
<Password>string</Password>
</AuthHeader>
</soap:Header>
<soap:Body>
<WS_GetData xmlns="http://tempuri.org/">
<xmlString>string</xmlString>
</WS_GetData>
</soap:Body>
</soap:Envelope>
Response
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?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>
<WS_GetDataResponse xmlns="http://tempuri.org/">
<WS_GetDataResult>string</WS_GetDataResult>
</WS_GetDataResponse>
</soap:Body>
</soap:Envelope>
Can anybody please gimme a sample code on how to consume such a service.
Many thanks in advance!
This is the code that i have used to call the web service
<?php
$soap_client = new SoapClient("http://172.160.0.49/OxiWalletService/Service.asmx?WSDL");
$Uid='oxigen';
$Pwd='oxigen';
$ns = "http://tempuri.org/";
//Body of the Soap Header.
$headerbody = array('UserName' => $Uid,
'Password' => $Pwd
);
//Create Soap Header.
$header = new SOAPHeader($ns, 'AuthHeader', $headerbody);
//set the Headers of Soap Client.
$soap_client->__setSoapHeaders($header);
$par="<Wallet><SPName>AuthenticateMerchantWebVending</SPName><Parameters><Parameter><Name>#Account</Name><Size>50</Size><Value>1135600016</Value><Type>varchar</Type></Parameter><Parameter><Name>#Password</Name><Size>20</Size><Value>0OgknrdonyM=</Value><Type>varchar</Type></Parameter></Parameters><ParameterCount>2</ParameterCount><DataBase>1</DataBase></Wallet>";
$param=array('xmlString'=>$par);
$result=$soap_client->__SoapCall('WS_GetData',$param);
print_r ($result);
?>
and i am getting the following as output:
stdClass Object ( [WS_GetDataResult] => 2Unknown Error )
Ideas??
So it turns out you've to pass the second argument with parameters as the key of the array
meaning this
$result=$soap_client->__SoapCall('WS_GetData',$param);
should be
$result=$soap_client->__SoapCall('WS_GetData',array('parameters'=>$param));
This works now.
I think this should do the trick:
www.php.net/manual/en/soapclient.setsoapheaders.php
$ns = "http://tempuri.org/"
//Body of the Soap Header.
$headerbody = array('UserName' => $yourUsername,
'Password' => $yourPassword,
);
//Create Soap Header.
$header = new SOAPHeader($ns, 'AuthHeader', $headerbody);
//set the Headers of Soap Client.
$soap_client->__setSoapHeaders($header);

PHP SOAP client help!

I have to create a PHP SOAP client that sends leads, but I have never worked with SOAP before, and my XML isn't that great, here is the code I have managed to write so far. . .
<?php
try {
$client = new SoapClient(null, array(
'location' => "https://wwa.website.co.za/CallmasterTes/LeadService.asmx",
'uri' => "urn:Website:Callmaster:InTuch/CreateLead",
'login' => "username",
'password' => "password"
));
$sysName = ' ';
$clientCode = ' ';
$expTimestamp = ' ';
$schedTimestamp = ' ';
$client->CreateLead("ExternalLead",
new SoapParam($sysName, "BusinessSystemName"),
new SoapParam($clientCode, "BusinessSystemClientCode"),
new SoapParam($_POST['Title'], "Title"),
new SoapParam($_POST['FirstName'], "FirstName"),
new SoapParam($_POST['Surname'], "Surname"),
new SoapParam($_POST['IdNumber'], "IdNumber"),
new SoapParam($_POST['Gender'], "Gender"),
new SoapParam($_POST['DateOfBirth'], "DateOfBirth"),
new SoapParam($_POST['Language'], "Language"),
new SoapParam($_POST['EmailAddress'], "EmailAddress"),
new SoapParam($_POST['HomeTelNumber'], "HomeTelNumber"),
new SoapParam($_POST['BusinessTelNumber'], "BusinessTelNumber"),
new SoapParam($_POST['MobileTelNumber'], "MobileTelNumber"),
new SoapParam($_POST['OtherTelNumber'], "OtherTelNumber"),
new SoapParam($_POST['PreferredTelNumberCode'], "PreferredTelNumberCode"),
new SoapParam($_POST['CampaignName'], "CampaignName"),
new SoapParam($_POST['ProductName'], "ProductName"),
new SoapParam($_POST['Comments'], "Comments"),
new SoapParam($expTimestamp, "ExpiryTimestamp"),
new SoapParam($schedTimestamp, "ScheduledTimestamp"),
);
}
catch (SoapFault $fault) {
trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR);
}
?>
The following is a sample SOAP 1.2 request and response that I was given by the developers on the server side of things.
POST /CallmasterTest/LeadService.asmx HTTP/1.1
Host: wwa.website.co.za
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<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>
<CreateLead xmlns="urn:Website:Callmaster:InTuch">
<Lead>
<BusinessSystemName>string</BusinessSystemName>
<BusinessSystemClientCode>int</BusinessSystemClientCode>
<Title>Mr or Ms or Mrs or Miss...etc</Title>
<FirstName>string</FirstName>
<Surname>string</Surname>
<IdNumber>string</IdNumber>
<Gender>Male or Female</Gender>
<DateOfBirth>date</DateOfBirth>
<Language>string</Language>
<EmailAddress>string</EmailAddress>
<HomeTelNumber>string</HomeTelNumber>
<BusinessTelNumber>string</BusinessTelNumber>
<MobileTelNumber>string</MobileTelNumber>
<OtherTelNumber>string</OtherTelNumber>
<PreferredTelNumberCode>Business or Home or Mobile or Other</PreferredTelNumberCode>
<CampaignName>string</CampaignName>
<ProductName>string</ProductName>
<Comments>string</Comments>
<ExpiryTimestamp>dateTime</ExpiryTimestamp>
<ScheduledTimestamp>dateTime</ScheduledTimestamp>
</Lead>
</CreateLead>
</soap12:Body>
</soap12:Envelope>
The response:
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<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>
<CreateLeadResponse xmlns="urn:Website:Callmaster:InTuch">
<CreateLeadResult>
<Success>boolean</Success>
<StatusMessage>string</StatusMessage>
<LeadGuid>guid</LeadGuid>
<Errors>
<LeadError ErrorLevel="Information or Warning or Error">
<Message>string</Message>
<Field>string</Field>
</LeadError>
<LeadError ErrorLevel="Information or Warning or Error">
<Message>string</Message>
<Field>string</Field>
</LeadError>
</Errors>
</CreateLeadResult>
</CreateLeadResponse>
</soap12:Body>
</soap12:Envelope>
I have really tried everything, and googled into high heaven, but I just can't get it to work, I am sure that it's probably something small that I am missing, I would really appreciate the help, thanx!
I'm not sure if this is a copy/paste error or not, but all the _POSTs should be $_POSTs in your first code example.

Categories