【问题标题】:Need help building a webservice called Nusoap需要帮助构建一个名为 Nusoap 的网络服务
【发布时间】:2011-03-22 20:47:43
【问题描述】:

在尝试解决此问题时遇到重大问题,我很乐意向可以帮助我完成这项工作的人提供 +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-&gt;getCustomer() 时,我收到以下错误:

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

我做错了什么?

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

【问题讨论】:

标签: php web-services nusoap soapheader


【解决方案1】:

我可能没有抓住重点,但您实际上从未将返回的对象分配给$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-&gt;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-&gt;request 是未来的便捷调试工具。

【讨论】:

  • @Click Upvote 我认为新的更新应该可以解决您的问题。
  • 嗯,这并没有给出任何错误但也没有给出任何输出?
  • @click 好吧,如果您执行var_dump,它确实显示为 false,根据文档,这意味着无效的用户数据。我不知道该测试信息是否用于实际测试或更多示例。因此,如果您有实际数据可用于测试,请尝试使用它来代替测试变量。
  • @Click Upvote 对我来说最终更新,但它似乎在做某事而不是返回错误。从这里开始祝你好运。
  • 谢谢,你似乎是这里的赢家......将不得不做更多的测试
【解决方案2】:

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

【讨论】:

  • 那是 php soapclient,而我调用的是 Nusoap soapclient。
  • @Click Upvote,您确定您实际上是在加载它吗?在我看来,这就像class nusoap_client
  • 你说得对,我将 SoapClient 更改为 Nusoap_client,现在它给出了以下输出:Array ( [faultcode] =&gt; soap:Client [faultstring] =&gt; Server did not recognize the value of HTTP Header SOAPAction: . [detail] =&gt; )
  • 仍然收到相同的错误,但是如果我将 $wsdl 设置为 true,即 $client = new nusoap_client($url, true);,我会收到不同的错误.. 请参阅我对问题的编辑
  • @Click Upvote,不,我检查了 nusoap 发送到服务的内容以查看问题的根源。 SOAP-ENV 被硬编码到它的源代码中,所以如果 eWay 不允许它(似乎是这种情况),我会说你不能成功使用这个库(不调整源代码)。我现在住的地方已经很晚了,祝你好运,我建议查看我提供的链接,我很确定那里的代码可以正常工作
【解决方案3】:

所以这里是:

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

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

【讨论】:

  • 我也有点困惑,因为你在getCustomers() 中创建了一个new SoapClient,但你说你应该使用 Nu Soap。你不应该创建new nusoap_client吗?
  • 嗨,是的,我已将 SoapClient 更改为 Nusoap_Client,现在我得到了不同的输出。请参阅我对问题的编辑。有什么想法吗?
【解决方案4】:

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

关于您提到的 HTTP "SOAPAction" 标头,我遇到了类似的错误。 (但是,我正在处理与您不同的 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 Header 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-03-08
  • 2017-10-25
  • 2012-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-07
  • 1970-01-01
  • 2011-09-05
相关资源
最近更新 更多