需要帮助构建一个名为Nusoap的Web服务

时间:2011-03-22 20:47:44

标签: php web-services nusoap soapheader

在尝试解决这个问题时遇到了重大问题,我很乐意为可以帮助我完成这项工作的人提供+500赏金。

基本上,我正在尝试使用Nusoap调用此Web服务:

https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=QueryCustomer

这是我到目前为止所得到的:

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);
    }
}

当我运行此代码并执行$eway->getCustomer()时,我收到以下错误:

Array
(
    [faultcode] => soap:Client
    [faultstring] => eWayCustomerID, Username and Password needs to be specified in the soap header.
)

我做错了什么?

如果您可以修复我的课程并给我工作代码,该代码能够使用测试客户ID执行QueryCustomer方法并返回其信息,我将很高兴为您提供+500代表和我永恒的感激之情。显然,我可以在48小时之前开始赏金,但我保证会这样做。

4 个答案:

答案 0 :(得分:4)

我可能会忽略这一点,但您实际上从未将返回的对象分配给$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);
}

如果需要,您还可以将$client设置为类变量,或者将参数作为参考发送。


查看数据,我不知道这是否重要,但您使用var作为类变量声明,然后使用private作为函数。如果您使用的是php5,我会远离var

private $username = 'test@eway.com.au';
private $pw = 'test123';
private $customerId = '87654321';

使用privatepublicprotected(根据您的班级要求)来保持一致性。我怀疑这会解决你的问题,只是需要注意的事情。


可能的解决方案

好的,做一些我自己的想法,想出这个,你需要包含你在SOAP:Header交易中添加的实际标题。我测试了下面的内容,它对我有用,所以试一试:

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;
}

它没有返回任何错误。所以,似乎这可能是罪魁祸首。 (注意我也实现了上面提到的$client = $this->setHeaders($client);


我的最终答案是:

好的做了一点挖掘,找到了有用的东西。不是说它是对的,但它确实有效。

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.
}

似乎namespacesoapAction是关键因素。我使用您最初发布的链接找到了这些:https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=QueryCustomer

基本上,我只是查看了那个响应,然后做了一些搜索以找出soapAction,然后只是弄乱了它,直到发送的请求与你发布的页面匹配。它返回失败的登录,但是,是的。这通常意味着某些东西正在运行,可能是由于测试数据。但这会给你一个基线。

$client->request是未来的一个方便的调试工具。

答案 1 :(得分:1)

更新5: nusoap实际上用SOAP-ENV包装请求,如:

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

虽然必须使用EWay soap:Header的文档。我在nusoap标题中找不到后者。

更新4: 这个link有一个很好的提示:

  

知道了。这是一个案例问题,但没有   那里,他们的PDF不正确。

     

对于那些得到这个的人   未来,PDF说:

     

<eWAYHeader xmlns="http://www.eway.com.au/gateway/managedPayment">   它应该是:

     

<eWAYHeader xmlns="https://www.eway.com.au/gateway/managedpayment">

答案 2 :(得分:0)

所以就在这里:

$client->setHeaders($headers);

SoapClient类没有该方法。相反,您可以创建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;
}

修改:好的,深入挖掘:

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);
}

如果你这样做会怎么样?

答案 3 :(得分:0)

我知道这不是问题的完整解决方案,但是虽然这个问题已经很久了,但我的发现可能有助于解决这个问题。

与您提及 HTTP“SOAPAction”标题相比,我遇到了类似的错误。 (但是,我正在处理一个与你不同的eWay API。我正在处理“Rapid API”,上周被重命名为“Merchant Hosted Payments”,这也是我的剧本之所以没有'工作)。

为了回到这一点,我发现如果你没有指定HTTP“SOAPAction”标头,eWay会返回一个带有以下错误消息的SoapFault。

“System.Web.Services.Protocols.SoapException:无法处理没有有效操作参数的请求。请提供有效的soap操作。”

如果添加HTTP“SOAPAction”标头,无论您将其设置为什么,都会收到错误。

“System.Web.Services.Protocols.SoapException:服务器无法识别HTTP标头SOAPAction的值:XXX”

eWay的支持人员也告诉我,他们遇到了内部重定向问题,他们现在正在考虑解决问题。

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