2

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.

Starx
  • 77,474
  • 47
  • 185
  • 261
Ali
  • 261,656
  • 265
  • 575
  • 769
  • 1
    If you're using the normal PHP `SoapClient`, shouldn't the method be `__setSoapHeaders`? – Marek Karbarz Mar 22 '11 at 20:55
  • 4
    You know, you've not actually added the bounty... – dotalchemy Mar 22 '11 at 20:57
  • @Marek I'm supposed to be using the Nusoap soap client.. I'm trying to use the example from here: http://www.richardkmiller.com/files/msnsearch_nusoap.html – Ali Mar 22 '11 at 20:59
  • @dotal I will add it as soon as it lets me. You can see that I've given bounties in the past : http://stackoverflow.com/questions/576908/how-does-magento-code-work – Ali Mar 22 '11 at 21:00
  • Just to make sure - you are referencing the needed Nusoap files, correct? – Marek Karbarz Mar 22 '11 at 21:00
  • @Marek I'm including `lib/nusoap.php`. That file seems to have a SoapClient class in itself. – Ali Mar 22 '11 at 21:02
  • In that case, check your spelling - the Nusoap version seems to be `soapclient` while PHP is `SoapClient` (as far as I can remember PHP is case sensitive). So you think you're using Nusoap, but you're actually trying to use PHP version of the client (you might need to use `nusoap_client` if PHP soap extensions are loaded). – Marek Karbarz Mar 22 '11 at 21:05
  • @Marek thanks, see my edit. Feel free to post your response as an answer – Ali Mar 22 '11 at 21:13

4 Answers4

4

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.

Jim
  • 18,673
  • 5
  • 49
  • 65
  • @Click Upvote I think the new update should solve your problem. – Jim Mar 22 '11 at 22:10
  • Hm, this doesn't give any errors but also doesn't give any output? – Ali Mar 22 '11 at 22:27
  • @click Well, if you do a `var_dump` it does show false, which according to the documentation means invalid user data. I do not know if that test information is used for actual testing or more for an example. So if you have actual data to use to test with, try that in place of the test variables. – Jim Mar 22 '11 at 22:42
  • @Click Upvote Final update for me, but it seems to be doing something instead of returning errors. Good luck from here on. – Jim Mar 22 '11 at 23:28
  • Thanks, you seem to be the winner here... will have to do a bit more of testing – Ali Mar 23 '11 at 08:00
  • This code gives a login error when I try it with the test info, I won't be able to test it with a live account, but I think that should work, so I'll give you the bounty when it allows me to. Thanks! – Ali Mar 25 '11 at 11:44
1

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">

Fluffy
  • 27,504
  • 41
  • 151
  • 234
  • That's the php soapclient, whereas I'm calling the Nusoap soapclient. – Ali Mar 22 '11 at 20:58
  • @Click Upvote, are you sure you're actually loading it instead? It looks like `class nusoap_client` to me – Fluffy Mar 22 '11 at 21:02
  • You're right, I changed SoapClient to Nusoap_client and its now giving this output: `Array ( [faultcode] => soap:Client [faultstring] => Server did not recognize the value of HTTP Header SOAPAction: . [detail] => )` – Ali Mar 22 '11 at 21:06
  • Still getting the same error, however if I set $wsdl to true, i.e `$client = new nusoap_client($url, true);`, I get a different error.. see my edit to the question – Ali Mar 22 '11 at 21:30
  • @Click Upvote, no I've checked what nusoap sends to the service to see the source of the problem. SOAP-ENV is hardcoded to its sources, so in case eWay doesn't allow it (which seems to be the case), I'd say that you can't succeed using this lib (without tweaking sources). It's late night where I live now, so good luck, I suggest looking into the link I provided, I'm pretty sure the code from there works fine – Fluffy Mar 22 '11 at 22:23
0

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.
Tim Post
  • 33,371
  • 15
  • 110
  • 174
magnus
  • 4,031
  • 7
  • 26
  • 48
  • 1
    Please come back and 'finalize' this once you've gotten to a resolution. Answers are typically reserved _only_ for direct answers to the question, but it looks like you might be close to providing that. If you don't update this soon, however, it will very likely be removed. I'm leaving it for now. – Tim Post May 28 '12 at 16:08
0

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?

Michael McTiernan
  • 5,153
  • 2
  • 25
  • 16
  • I'm also a bit confused since you create a `new SoapClient` within `getCustomers()`, but you say you're supposed to be working with Nu Soap. Shouldn't you be creating `new nusoap_client`? – Michael McTiernan Mar 22 '11 at 21:15
  • Hi, yes, I've changed SoapClient to Nusoap_Client and I'm getting a different output now.. see my edit to the question. Any ideas about that? – Ali Mar 22 '11 at 21:17