mytharcher/alipay-php-sdk

使用 wap 付款,curl 结果为空

Closed this issue · 17 comments

试了下wap 付款

  1. curl_exec 返回为空,
    2.curl_error 没有错误信息.
    3.看curl_getinfo的结果,返回是302, 给了个 redirect url.
    浏览器直接访问get 的 url, 出现支付宝的系统繁忙页面.

是不是和我上传的 ssl 证书有关? 支付宝不支持 md5了,只能用RSA 方式?

谢谢啦.

不好意思,没有用 crul 测试过,一直是用在 web 里。支付宝应该还支持 MD5 验证的,我客户的项目依然可以收到付款。另外我还没用过 ssl 的证书,你试试返回地址https的行不行。

这个项目主要把一些接口给统一了,测试写的不是很完善,demo 里基本可用,不排除有 bug,可能需要自己花点时间调试一下。

cnxh commented
use DOMDocument;

哦,对,更新的适配 composer 版本中,要使用命名空间:

use mytharcher\sdk\alipay;

或者:

new mytharcher\sdk\alipay\Alipay();

谢谢 @mytharcher @cnxh

  1. 因为没有配置 config/app.php 的 provider。 所以 需要使用 use \mytharcher\sdk\alipay (从root开始);
  2. Alipay.php 里,正如 @cnxh 所说,需要 use \DOMDocument;
  3. curl 终于有结果了
$alipay = new \mytharcher\sdk\alipay\Alipay($alipay_config, TRUE);
$params = $alipay->prepareMobileTradeData(array(...));
$body =  $alipay->buildRequestFormHTML($params, 'get');

然而返回的form,url是 http的,所以会有个安全警告。(因为我全站是https)

建议:

  1. alipay_config 使用vendor:publish 后 copy 一个config文件到 config/xxx.config. 便于维护
    2。form 的url 根据 config里的 transport 类型来做判断。

现在已经能出现支付宝wap页面了。
等空了我试试看 后台的 notify url 和 return url,目前我用web版本的验证方式是错误的,支付宝返回的格式好像是统一的。 再次感谢!

对Alipay.php 的改动,我做的是:

use \DOMDocument;
var $alipay_gateway_mobile = 'https://wappaygw.alipay.com/service/rest.htm?';
 var $verify_url            = 'https://notify.alipay.com/trade/notify_query.do?';

没有做https的判断,因为http到https是不会有警告的。

多谢两位。

另外 @unidotnet 你能帮测试下改成https$verify_url么,我用curl直接访问了下无法连接。

@mytharcher 的确不能访问,因为我用https了,所以只会访问 verify_url_https 。
我把不是https的verify_url 改回成 http了。。。 不好意思误导你了。

好的,那我暂时就不修改这两个地址了。

不过我发现代码里之前$alipay_gateway_mobile这个变量完全没有用到,我干脆去掉好了。

$alipay_gateway_mobile 这个要改的,根据 protocol 来用 https 还是 http, 不然https的网站会跳到http的gateway会出现安全警告。

恩,移动端的已经统一用https://mapi.alipay.com/gateway.do?这个地址了。

上面一个修改是疏漏了,暂时先还原了。回头整理下协议部分抽取出来一起改。

今天试了下验证:

$alipay = new Alipay(array(/* config */));
$result = $alipay->verifyCallback();

返回结果是出错了。。
local.ERROR: exception 'ErrorException' with message 'Undefined index: notify_id' in /var/www/html/test/vendor/mytharcher/alipay-php-sdk/Alipay.php:260

粗略看了下,POST请求:

'service' => 'alipay.wap.trade.create.direct',
  'sign' => 'xxx',
  'sec_id' => 'MD5',
  'v' => '1.0',
  'notify_data' => '
<notify>
    <payment_type>1</payment_type>
    <subject>xxx</subject>
    <trade_no>000000</trade_no>
    <buyer_email>sss@ss.com</buyer_email>
    <gmt_create>2015-08-27 12:44:53</gmt_create>
    <notify_type>trade_status_sync</notify_type>
    <quantity>1</quantity>
    <out_trade_no>xxx</out_trade_no>
    <notify_time>2015-08-27 12:44:55</notify_time>
    <seller_id>888888</seller_id>
    <trade_status>TRADE_SUCCESS</trade_status>
    <is_total_fee_adjust>N</is_total_fee_adjust>
    <total_fee>0.01</total_fee>
    <gmt_payment>2015-08-27 12:44:55</gmt_payment>
    <seller_email>xx@xx.com</seller_email>
    <price>0.01</price>
    <buyer_id>8888888</buyer_id>
    <notify_id>xx</notify_id>
    <use_coupon>N</use_coupon>
</notify>',
) 

notify_id 是有的,大概解析错了吧。

260行 $notify_id = $data['notify_id']; 这个notify_id 是不在data的json里的, 是在xml里的。

我把方法给重写了下:

function verifyCallback(&$request) {
        ...
        //$notify_id = $data['notify_id'];
        $notify_id = '';
        if ($async && $this->is_mobile){
            ....

            $notify_id = $doc->getElementsByTagName( 'notify_id' )->item(0)->nodeValue;
            $params=$doc->childNodes->item(0)->childNodes;
            foreach($params as $param) {
                $request->merge([$param->nodeName=>$param->nodeValue]);
            }
        }

        ....
               return $signValid && preg_match("/true$/i", $responseTxt);
    }

使用方法:

if(!$alipay->verifyCallback($request)){
                return 'fail';
            }

这样的话,会给$request增加必要到键值,可以和后续的web或者mobile操作方便整合。

多谢测试,能麻烦发个 PR 我 diff 一下然后合并么?

等我有空了给你哦

$notify_id = $data['notify_id'];这个问题在最新版本里已经修复: 4754e0a