2

在尝试解决此问题时遇到重大问题,我很乐意向可以帮助我完成这项工作的人提供 +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

4 回答 4

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

使用privateor publicor protected(无论你的班级需要什么)来保持一致性。我怀疑这会解决你的问题,只是需要注意的事情。


可能的解决方案

好的,我自己进行了一些挖掘,发现了这一点,您需要封装您在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是未来的方便调试工具。

于 2011-03-22T21:29:45.897 回答
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>

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

更新 4:此链接有一个很好的提示:

知道了。这是一个案例问题,但不存在,他们的 PDF 不正确。

对于将来得到这个的任何人,PDF 说:

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

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

于 2011-03-22T20:55:59.130 回答
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);
}

如果你这样做会发生什么?

于 2011-03-22T21:02:37.760 回答
0

我知道这不是该问题的完整解决方案,但是尽管这个问题已经很老了,但我的发现可能有助于找到具体的解决方案。

关于您提到的HTTP "SOAPAction" header,我遇到了类似的错误。(但是,我正在处理与您不同的 eWay API。我正在处理“Rapid API”,上周已从“Merchant Hosted Payments”重命名,这也是我的脚本没有的部分原因t 工作)。

回到正题,我发现如果您不指定 HTTP“SOAPAction”标头,eWay 会返回带有以下错误消息的 SoapFault。

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

如果添加 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.
于 2012-05-28T00:53:21.600 回答