Need help building a webservice called Nusoap - php

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.

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.

Get a Soap request

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.

JWT_Auth returning a token is required for getPayload even though one is supplied

I am using the JWT-Auth package in my Laravel 5.6 project.
I have a simple test which is using the getPayload method, but it keeps returning;
Tymon\JWTAuth\Exceptions\JWTException: A token is required
My method is as follows so far;
$user = factory(User::class)->create();
$token = JWTAuth::fromUser($user);
$payload = JWTAuth::getPayload($token);
If i do a dd($token) it spits out the users token correctly.
If anyone else has run into this, i would love some help.
Cheers
In your case, it would work if you call it as:
$payload = JWTAuth::setToken($token)->getPayload();
I had a look at the source class and it looks like the reason why ;
$payload = JWTAuth::getPayload($token);
returns A token is required error is that because it looks for $this->token variable. But when you set it using JWTAuth::fromUser($user); it doesn't set any value to it.
public function fromUser(JWTSubject $user)
{
return $this->fromSubject($user);
}
...
public function fromSubject(JWTSubject $subject)
{
$payload = $this->makePayload($subject);
return $this->manager->encode($payload)->get();
}
Here you can see that fromSubject() actually returns the payload. So the returned result of fromUser() should actually contain the payload you were looking for although I'm not sure about this as I'm unable to test.
Hope it helps :)

SOAP error. Not getting correct structure returned

I have a website that contains a form that makes various SOAP requests at certain points. One of these requests gets a list of induction times returned and displays them to the user in order for them to pick one.
I am getting results returned fine from the SOAP service but unfortunately it seems to be not showing information correctly and even not displaying returned object keys at all.
I have liased with one of the devs at the SOAP end and he says the service is fine and spitting out the cirrect information. He has provided a screentshot:
Here is my code to pull call the method I need for this information:
public function getInductionTimes($options) {
$client = $this->createSoapRequest();
$inductionTimes = $client->FITinductionlist($options);
//die(print_r($inductionTimes));
return $inductionTimes;
}
private function createSoapRequest() {
$url = 'https://fitspace.m-cloudapps.com:444/FITSPACE/MHservice.asmx?WSDL';
$options["connection_timeout"] = 25;
$options["location"] = $url;
$options['trace'] = 1;
$options['style'] = SOAP_RPC;
$options['use'] = SOAP_ENCODED;
$client = new SoapClient($url, $options);
//die(print_R($client->__getFunctions()));
return $client;
}
As you can see I print_r the code right after I have received it to check what I am getting returned and it is this:
As you can see this IDdtstring field is getting completely ignored.
Does anyone have any ideas as to why this may be happening? Is it something to do with encoding? I can't seem to get anywhere on this issue!
Thanks
I was able to retrieve the fields correctly, including IDdtstring, using your basic code. Perhaps you are not sending the parameters correctly?
function getInductionTimes($options) {
$client = createSoapRequest();
$inductionTimes = $client->FITinductionlist($options);
die(print_r($inductionTimes));
return $inductionTimes;
}
function createSoapRequest() {
$url = 'https://fitspace.m-cloudapps.com:444/FITSPACE/MHservice.asmx?WSDL';
$options["connection_timeout"] = 25;
$options["location"] = $url;
$options['trace'] = 1;
$options['style'] = SOAP_RPC;
$options['use'] = SOAP_ENCODED;
$client = new SoapClient($url, $options);
//die(print_R($client->__getFunctions()));
return $client;
}
getInductionTimes(array("IDDate" => "2013-06-28T13:00:00+01:00", "GYMNAME" => "Bournemouth"));
I managed to solve this issue by adding the line of code into my SOAP options array which I then presume was an issue with my WSDL being cached in PHP:
$options['cache_wsdl'] = WSDL_CACHE_NONE;

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.

Categories