Get a Soap request - php

Let me explain, I am doing something like a webservice in which I get information from a platform called Wialon, they use a section called repeaters where they send me a SOAP request to a specific address, I will be honest I have no idea how to use SOAP i never did something like this, so my question is how can i receive that SOAP data in PHP, so I can see it, I want to receive that SOAP request and i don't know save it in DB to see how it works or the structure, because these guys of wialon do not give information about what they send in that soap but I imagine it is an xml, so far I have tried to investigate but the truth is I do not know how soap works, im using this code that I found:
class MyClass {
public function helloWorld() {
require_once 'com.sine.controlador/Controlador.php';
$c = new Controlador();
$xml = $c->insertarResultado('06',func_get_args());
return 'Hello Welt ' . print_r(func_get_args(), true);
}
}
try {
$server = new SOAPServer(
NULL, array(
'uri' => 'http://localhost/WebserviceGLMS2/index.php'
)
);
$server->setClass('MyClass');
$server->handle();
} catch (SOAPFault $f) {
print $f->faultstring;
}
but it doesn't seem to work, hope you can help me, thanks

A soap request is nothing else than a xml post request. In PHP you can get the whole request body with the following code.
<?php
$content = file_get_contents('php://input');
var_dump($content);
You can use this unless it 's not multipart/formdata.

Related

SOAP API: PHP Code doesn't work, but SOAP UI works

I'm trying to create a rental module for my work's website. When I use the same parameters in SmartBear's SOAP UI, it works. So, I'm assuming that it's something to do with my code, but I cannot find the error.
<?php //Submit Reservation
require("connect.php");
$sessionId = $_SESSION['sessionId'];
$moveInDate = date("yy-m-d", strtotime($_POST['moveIn']));
$billDate = date("d", strtotime($_POST['moveIn']));
$rentalOptions = array(
"customer.company" =>$company,
"account.startDate"=> $moveInDate,
"contact.firstName"=>$_POST['fname'],
"contact.lastName"=>$_POST['lname'],
"contact.companyName"=>$_POST['companyName'],
"contact.street1"=>$_POST['street'],
"contact.street2"=>"",
"contact.city"=>$_POST['city'],
"contact.state"=>$_POST['state'],
"contact.zip"=>$_POST['zip'],
"contact.country"=>"US",
"phone.1" => $_POST['mobile'],
"contact.email"=>$_POST['email'],
"account.currency"=>"1",
"account.billDay"=> $billDate,
"user.paymentMethod"=>"1",
"user.draftDay"=>"",
"unit.id"=>$_POST['unit-name'],
"postAccount"=>"Y",
"promotionId"=>$_POST['promo'],
"insuranceId"=>$_POST['insurance']
);
var_dump($rentalOptions);
echo "<br/>". $sessionId ."<br/>Return";
$client = new SoapClient("https://api.doorswap.com/service/system.wsdl");
// Make API Call
$dsReceiver = "customer";
$dsAction = "saveNewCustomer";
$result = $client->makeReceiverCall($sessionId, $dsReceiver, $dsAction, $rentalOptions);
//if($result["success"] == "true") {
//}
?>
The var_dump() and print_r() displays correct variables from the previous form. In fact, ALL variables are correctly output. I just do not understand WHY it isn't working. It's not giving me an error, it's just not POSTING.
FYI: I have tried using javascript SOAP and I run into similar issues. The code is right, the variables are correct, but the addition to the system is not going through.
I'm open to trying anything.
Initialization of the SoapClient class
First of all inialize your soap client the right way. The soap client class takes several options to debug your application. In the following example a soap client is initalized with some options, that will make your life more easy when testing.
try {
$client = new SoapClient('https://api.doorswap.com/service/system.wsdl', [
'exceptions' => true,
'trace' => true,
]);
} catch (SoapFault $fault) {
var_dump($fault->getMessage());
if ($client instanceof SoapClient) {
var_dump(
$client->__getLastRequest(),
$client->__getLastResponse()
);
}
}
As you can see the soap client class is initialized with different option parameters. The exception option is set to true so that the soap client class throws exceptions, when an error occurs. That 's why the code is wrapped in a try and catch block. The trace option allows us to see, what the last request and response looks like. If the soap client was initialized you can use the build in methods __getLastRequest() and __getLastResponse() to see what the sent and received xml looks like. Keep in mind, that these can be empty if the xml wasn 't compiled by the client.
The makeReceiverCall method was a "name"/"value" system. So the above array of $rentalOptions SHOULD have been done as such. This is currently working, and has been flawless in execution.
$rentalOptions = array(
array("name"=> "customer.company","value"=> $company),
array("name"=> "account.startDate", "value"=> $moveInDate),
...
);
This was the error that I had run into and finally figured out. Thank you to all those who tried to help.

PHP Soap calling Error

I am trying to connect to webservice using SOAP / wsdl, but I constantly get the error. I am new in soap-api in php. I have a document of api detail, it shows:
public WSGetCalendarFareResponse GetCalendarFare(WSGetCalendarFareRequest calanderFareRequest)
I made my code accordingly but still found error/exception. Please review my php code in following:
$wsdl = "http://api.abc.com/xyz/service.asmx?wsdl"; // This is a test Web Service URL
$h = array();
$opta["GetCalendarFare"]["request"]= array(
"Origin"=>"DEL",
"Destination"=>"IXR",
"DepartureDate"=>"2015-05-01T00:00:00",
"ReturnDate"=>"2015-05-01T00:00:00",
"Type"=>"OneWay",
"CabinClass"=>"All",
"PreferredCarrier"=>"",
"AdultCount"=>1,
"ChildCount"=>1,
"InfantCount"=>"0",
"SeniorCount"=>"0",
"PromotionalPlanType"=>"Normal",
"IsDirectFlight"=>false
);
$client_header = new SoapHeader('http://192.168.0.0/TEST/BookingAPI','AuthenticationData',$hparams,false);
$cliente = new SoapClient($wsdl, array('trace' => 0));
$cliente->__setSoapHeaders(array($client_header));
try{
$h= (array)$cliente->__call('GetCalendarFare',$opta);
}catch(Exception $e)
{
echo '<pre>';
var_dump($e);
}
When I execute my code, it returns following error:
"System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at BookingAPI.WSCalendarFareInput(WSGetCalendarFareRequest calanderFareRequest) in c:\inetpub\wwwroot\api.tektravel.com\TboApi_V7\App_Code\Service.cs:line 4544
at BookingAPI.GetCalendarFare(WSGetCalendarFareRequest calanderFareRequest) in c:\inetpub\wwwroot\api.tektravel.com\TboApi_V7\App_Code\Service.cs:line 4360
Can anyone please suggest that where problem exists? It hit & try many times but couldn't get the error point.
Can you debug the execution of your POST on the server side? It is heavy guessing from my side, but I assume that you do not set a mandatory value in the request, which the server needs to deserialize your object. Hence the NullReferenceException.
Problem has resolved.
The Request array should be like this:
$opta["GetCalendarFare"]["calanderFareRequest"]= array(
"Origin"=>"DEL",
"Destination"=>"IXR",
"DepartureDate"=>"2015-05-01T00:00:00",
"ReturnDate"=>"2015-05-01T00:00:00",
"Type"=>"OneWay",
"CabinClass"=>"Economy",
"PreferredCarrier"=>"",
"AdultCount"=>1,
"ChildCount"=>1,
"InfantCount"=>"0",
"SeniorCount"=>"0",
"PromotionalPlanType"=>"Normal",
"IsDirectFlight"=>false
);

PHP SOAP service returns Value cannot be null. Parameter name: s

I'm trying upload orders to a remote server with soap but when I send the XML what the SOAP expects I got this error:
Exception: System.ArgumentNullException
Message: Value cannot be null.
Parameter name: s
Stack trace: at System.IO.StringReader..ctor(String s)
at System.Xml.XmlDocument.LoadXml(String xml)
I'm calling the service like this:
<?php
$doc = new DomDoument('1.0', 'UTF-8');
$doc->formatOutput = true;
/* lots of code here */
$xml = saveXML();
$client = new SoapClient('http://mx.biopont.com/services/Vision.asmx?wsdl',array("trace" => 1, 'features' => SOAP_SINGLE_ELEMENT_ARRAYS));
//$result = $client->RendelesFeladas(array('rendelesxml' => $xml));
try {
$result = $client->__soapCall('RendelesFeladas', array("rendelesxml"=>$xml));
}catch (SoapFault $e) {
echo "SOAP Fault: ".$e->getMessage()."<br />\n";
}
?>
the XML which is generated by DOMDocument is look like this
<?xml version="1.0" encoding="UTF-8"?>
<rendeles verzio="1.0">
<fej>
<partnerid>4476</partnerid>
<idegen_megrendelesszam>d836033</idegen_megrendelesszam>
<szallitasi_mod>51</szallitasi_mod>
<szallitasi_megj>gfhgfhgfhfhh</szallitasi_megj>
</fej>
<tetelek>
<tetel>
<tetelszam>1</tetelszam>
<cikkszam>102050009</cikkszam>
<mennyiseg>1</mennyiseg>
</tetel>
</tetelek>
</rendeles>
I don't have a clue what did i wrong. Because I construct the XML according to an example file which I got from the developer of the web-service. And actualy at the very first time I ran the call everything went fine since than I get error, and I didn't made changes to the xml, there were no changes in the SOAP service. So I don't get it.
Can somebody help me, point out what am I doing wrong?
Ok I found it.
For the partner who runs under the ID 4476 I added a fake ZIP code and the soap service couldn't figure out what to do whit it so the user 4476 was corrupted. After I updated the address information the order was accepted by the soap service.

Soap not getting sent correctly, need to get the request

I have this class to send a SOAP-request (the class also defines the header)
class Personinfo
{
function __construct() {
$this->soap = new SoapClient('mysource.wsdl',array('trace' => 1));
}
private function build_auth_header() {
$auth->BrukerID = 'userid';
$auth->Passord = 'pass';
$auth->SluttBruker = 'name';
$auth->Versjon = 'v1-1-0';
$authvalues = new SoapVar($auth, SOAP_ENC_OBJECT);
$header = new SoapHeader('http://www.example.com', "BrukerAutorisasjon", // Rename this to the tag you need
$authvalues, false);
$this->soap->__setSoapHeaders(array($header));
}
public function hentPersoninfo($params){
$this->build_auth_header();
$res = $this->soap->hentPersoninfo($params);
return $res;
}
}
The problem is that there's something wrong with my function and the response is an error. I'd like to find out what content I am sending with my request, but I can't figure out how.
I've tried a try/catch-block in the hentPersoninfo-function that calls $this->soap->__getLastRequest but it is always empty.
What am I doing wrong?
Before I ever start accessing a service programmatically, I use SoapUI to ensure that I know what needs sent to the service, and what I should expect back.
This way, you can ensure the issue isn't in the web service and/or in your understanding of how you should access the web service.
After you understand this, you can narrow your focus onto making the relevant SOAP framework do what you need it to do.

Need help building a webservice called Nusoap

Been having major issues trying to solve this issue, I'll be happy to give a +500 bounty to someone who can help me get this work.
Basically, I'm trying to call this web service using Nusoap:
https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=QueryCustomer
This is what I've got so far:
class Eway
{
var $username = 'test#eway.com.au';
var $pw = 'test123';
var $customerId = '87654321';
private function setHeaders($client)
{
$headers = <<<EOT
<eWAYHeader xmlns="http://www.eway.com.au/gateway/managedPayment">
<eWAYCustomerID>$this->customerId</eWAYCustomerID>
<Username>$this->username</Username>
<Password>$this->pw</Password>
</eWAYHeader>
EOT;
$client->setHeaders($headers);
return $client;
}
function getCustomer($ewayId = 9876543211000)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new Nusoap_client($url, true);
$this->setHeaders($client);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args);
print_r($result);
}
}
When I run this code and do $eway->getCustomer() I get the following error:
Array
(
[faultcode] => soap:Client
[faultstring] => eWayCustomerID, Username and Password needs to be specified in the soap header.
)
What am I doing wrong?
If you could fix my class and give me working code which is able to do the QueryCustomer method using the test customer id and return its info, I'll be glad to give you +500 rep and my eternal gratitude. Obviously it'll be 48 hours before I can start the bounty, but I promise that I will do it.
I could be missing the point, but you never actually assign the returned object to $client:
function getCustomer($ewayId = 9876543211000)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new Nusoap_client($url, true);
$client = $this->setHeaders($client);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args);
print_r($result);
}
You could also set $client as a class variable if desired or by sending the parameter as a reference.
Looking at the data, I do not know if this matters, but you are using var for your class variable declarations and then using private for the function. If you are using php5 I would stay away from the var:
private $username = 'test#eway.com.au';
private $pw = 'test123';
private $customerId = '87654321';
Use the private or public or protected (whichever your class requires) instead to keep consistency. I doubt this will solve your problem, just something to be conscious about.
Possible Solution
Ok, doing some digging of my own, figured this out, you need to encase the actual header you add in a SOAP:Header deal. I tested the below and it was working for me, so give it a try:
private function setHeaders($client)
{
$headers = <<<EOT
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP:Header>
<eWAYHeader xmlns="http://www.eway.com.au/gateway/managedPayment">
<eWAYCustomerID>$this->customerId</eWAYCustomerID>
<Username>$this->username</Username>
<Password>$this->pw</Password>
</eWAYHeader>
</SOAP:Header>
EOT;
$client->setHeaders($headers);
return $client;
}
It did not return any errors. So yea, it seems that is the likely culprit. (Note I also implemented the $client = $this->setHeaders($client); I mentioned above as well.
And my Final Answer is:
Alright did a bit of digging and found something that works. Not saying it is right, but yea it works.
private function setHeaders($client)
{
$headers = <<<EOT
<eWAYHeader xmlns="https://www.eway.com.au/gateway/managedpayment">
<eWAYCustomerID>$this->customerId</eWAYCustomerID>
<Username>$this->username</Username>
<Password>$this->pw</Password>
</eWAYHeader>
EOT;
$client->setHeaders($headers);
return $client;
}
function getCustomer($ewayId = 123456789012)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new nusoap_client($url);
$client = $this->setHeaders($client);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args, $namespace='https://www.eway.com.au/gateway/managedpayment', $soapAction='https://www.eway.com.au/gateway/managedpayment/QueryCustomer');
print_r($result);
//echo "\n{$client->request}\n"; // This echos out the response you are sending for debugging.
}
It seems the namespace and soapAction were the key ingredients. I found these using the link you originally posted: https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=QueryCustomer
Basically, I just looked at that response, and then did some searching to figure out the soapAction, and then just messed with it until the request being sent matched the page you posted. It returns a failed login, but yea. That generally means something is working, and is probably due to the test data. But that gives you a baseline to go off of.
And the $client->request is a handy debugging tool for the future.
Update 5:
nusoap actually wraps the request with SOAP-ENV, like:
<SOAP-ENV:Header><eWAYHeader xmlns="https://www.eway.com.au/gateway/managedpayment">
<eWayCustomerID>87654321</eWayCustomerID>
<Username>test#eway.com.au</Username>
<Password>test123</Password>
</eWAYHeader></SOAP-ENV:Header>
While in the docs for EWay soap:Header must be used. I couldn't find a mention of the latter in nusoap headers.
Update 4:
This link has a good tip:
Got it. It was a case issue but not
there, and their PDF is incorrect.
For anyone that gets this in the
future, the PDF says:
<eWAYHeader
xmlns="http://www.eway.com.au/gateway/managedPayment">
It should be:
<eWAYHeader
xmlns="https://www.eway.com.au/gateway/managedpayment">
So this right here:
$client->setHeaders($headers);
The SoapClient class doesn't have that method. Instead, you can create a new SoapHeader.
private function setHeaders($client)
{
$headers = new stdClass;
$headers->eWAYCustomerID = $this->customerId;
$headers->Username = $this->username;
$headers->Password = $this->pw;
$ewayHeader = new SoapHeader(
"http://www.eway.com.au/gateway/managedPayment",
"eWAYHeader",
$headers
);
$client->__setSoapHeaders(array($ewayHeader));
return $client;
}
Edit: Alright, digging deeper:
private function prepHeaders()
{
return array(
'eWAYHeader' => array(
'eWAYCustomerID' => $this->customerId,
'Username' => $this->username,
'Password' => $this->pw
)
);
}
function getCustomer($ewayId = 9876543211000)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new nusoap_client($url);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args, null, null, $this->prepHeaders());
print_r($result);
}
What happens if you do that?
I know this is not a full solution to the issue, but although this question is quite old, my findings may help lead to a concrete resolution.
I've been experiencing a similar error in relation to your mention of the HTTP "SOAPAction" header. (I am, however, dealing with a different eWay API than you. I'm dealing with the "Rapid API", which last week was renamed to from "Merchant Hosted Payments", which was part of the reason why my script wasn't working).
To return to the point, I found that if you don't specify the HTTP "SOAPAction" header, eWay returns a SoapFault with the following error message.
"System.Web.Services.Protocols.SoapException: Unable to handle request without a valid action parameter. Please supply a valid soap action."
If you add the HTTP "SOAPAction" header, you get an error no matter what you set it to.
"System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: XXX"
I'm also told by a member of eWay's support staff that they have an issues with an internal redirect, which they are now looking into resolving.
<ME> (2012-05-25 02:50:18)
I had an idea of what it could be. What is the "SOAPAction" HTTP header supposed to be set to?
<ME> (2012-05-25 02:52:05)
I couldn't find it in the documentation.
<EWAY_SUPPORT_STAFF> (2012-05-25 02:53:38)
The only thing that is required typically is the endpoint which is https://au.ewaypayments.com/hotpotato/soap.asmx and the <CreateAccessCode xmlns="https://au.ewaypayments.com/hotpotato/">
<EWAY_SUPPORT_STAFF> (2012-05-25 02:54:10)
In my tests it is working but what is happening is that requests are being redirected to the old URL which does not accept the CreateAccessCode method
<ME> (2012-05-25 02:56:58)
You did say that.
<ME> (2012-05-25 02:57:13)
So is this bug happening in the production environment?
<EWAY_SUPPORT_STAFF> (2012-05-25 02:57:57)
Yes it appears so. I have escalated this to Development and attached our last chat transcript and my own test results. They are looking at it now.

Categories