支付宝-担保交易 SIGN 生成问题

2015-01-23 03:26:28 +08:00
 konakona
现在在整合担保交易到项目中。

之前也多次开发过支付宝-担保交易的接口,因为支付宝各种接口相似度高,因此封装好后通用性就比较强,所以把以前的代码重写了下即可兼容担保交易的接口。

也在localhost新建了一个文件夹,实测了官方PHP UTF-8 DEMO的运作,DEMO一切正常,能够到达支付宝页面并正确读取出商品信息和价格等。

但是我的代码,死活签名验证不通过,打印数据如下:



第一段是打印数组,打印的是“待签名”的数组,可以确定没有问题(我仔细的核对过API的PD“4 请求参数说明”),这部分用的也是官方APIDemo 中的 buildRequestPara()方法。在这里,进行了签名生成。

签名一直过不了!

我是已经想不明白了……大半夜的……在蹲墙角ing……可能我明天起来换一个心情又运行了呢!!!(画圈圈去)
3131 次点击
所在节点    支付宝
13 条回复
Sunyanzi
2015-01-23 04:58:50 +08:00
输出的数组格式没问题 ... 所以原因只可能有三点 ...

第一检查你的 api key 有没有写对 ... 就是附在待签名部分尾巴上的那个 ...

第二你的待签名字符串根本没有打全让人怎么看 ...

第三也是可能性最大的一点 ... &not 在 html 里面是 ¬ 这个符号 ...

如果你是通过 HTML 跳转支付宝的时候记得转义 URL ... 细心比什么都重要 ...
Sunyanzi
2015-01-23 05:02:19 +08:00
咦我刚知道 V2 居然不转义 HTML 的吗 ... @Livid 这是个 feature 还是个 bug ..?

我是说 &not 在 HTML 里面是 ¬ 这个符号 ... 这会干扰到 notify 传值 ...
Livid
2015-01-23 05:03:45 +08:00
@Sunyanzi 谢谢反馈。我看一下。可能是 bug。
Sunyanzi
2015-01-23 05:07:55 +08:00
@Livid 好快!
Livid
2015-01-23 05:24:23 +08:00
@Sunyanzi Fixed.
xoxo
2015-01-23 08:31:18 +08:00
这个是不是因为楼主用了框架( $_GET['a'] $_GET['c'] )? 然后支付宝验签直接取的$_GET、$_POST
baocaixiong
2015-01-23 09:30:39 +08:00
@xoxo
如果框架对$_GET和$_POST修改过,需要重新赋值回来的。
cevincheung
2015-01-23 09:37:21 +08:00
@Sunyanzi 在HTML的显示不会影响到HTML值。

@konakona 不使用http_build_query就好了。
konakona
2015-01-23 15:12:47 +08:00
@Sunyanzi
@xoxo
@cevincheung
@baocaixiong
这个是发送过去的SIGN验证不通过,不是callback或者notify的时候,我这边不通过。
没有用http_build_query(),处理待签名数字和生成签名,都是用的官方DEMO里的函数。(本来我是自己写的,但是签名一直有问题,索性就将官方DEMO中的关键函数整个移植到了我的代码中,以肯定2者的处理方式一模一样)
所有数组ksort了,去掉了空格,生成了a=b&b=c&c=d这样的格式。
`
/**
* 生成要请求给支付宝的参数数组
* @param $para_temp 请求前的参数数组
* @return 要请求的参数数组字符串
*/
private function buildRequestParaToString($para_temp)
{
//待请求参数数组
$para = $this->buildRequestPara($para_temp);
dump($para);

//把参数组中所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串,并对字符串做urlencode编码
$request_data = createLinkstringUrlencode($para);
dump($request_data);

return $request_data;
}

/**
* 生成签名结果
* @param $para_sort 已排序要签名的数组
* return 签名结果字符串
*/
private function buildRequestMysign($para_sort)
{
//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
$prestr = $this->createLinkstring($para_sort);
$mysign = md5($prestr . $this->alipay_secret_key);
return $mysign;
}

/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
* @param $para 需要拼接的数组
* return 拼接完成以后的字符串
*/
private function createLinkstring($para)
{
$arg = "";
while (list ($key, $val) = each($para)) {
$arg .= $key . "=" . $val . "&";
}
//去掉最后一个&字符
$arg = substr($arg, 0, count($arg) - 2);

//如果存在转义字符,那么去掉转义
if (get_magic_quotes_gpc()) {
$arg = stripslashes($arg);
}

return $arg;
}

`
cevincheung
2015-01-23 15:19:01 +08:00
@konakona

function get_payment_url($trade_id,$price) {

$url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']."?action=notify";

$partner = 'xxxx';
$secret = 'xxxxxxxxx';

$p = array();

$p['logistics_type'] = 'EXPRESS';
$p['logistics_fee'] = '0';
$p['logistics_payment'] = 'BUYER_PAY_AFTER_RECEIVE';

$p['service'] = 'create_direct_pay_by_user';
$p['partner'] = $partner;
$p['_input_charset'] = 'utf-8';
$p['notify_url'] = $url;
$p['return_url'] = $url;
$p['out_trade_no'] = $trade_id;
$p['subject'] = "支付订单 {$trade_id}";
$p['payment_type'] = 1;
$p['seller_id'] = $partner;
//$p['total_fee'] = $price;
$p['price'] = $price;
$p['quantity'] = 1;
$p['body'] = "支付订单 {$trade_id}";
ksort($p);

$sign_str = null;foreach ($p as $k=>$v) $sign_str .= "{$k}={$v}&";$sign_str = substr($sign_str,0,-1);

$p['sign'] = md5($sign_str.$secret);
$p['sign_type'] = 'MD5';

$query_string = http_build_query($p);

return 'https://mapi.alipay.com/gateway.do?'.$query_string;

}



签名的值不能经过urlencode
konakona
2015-01-23 15:20:27 +08:00
@Sunyanzi
=.= 果然..我刚刚恍然大悟...尼玛用HTML生成的含有&not被转义后的URL肯定访问不了..现在已经OK了!
Sunyanzi
2015-01-23 16:28:12 +08:00
@cevincheung 再多学学吧 ...

@konakona 我总觉得最悲哀的事莫过于我告诉了你答案你自己还要琢磨很久才看明白 ...
konakona
2015-01-23 23:05:32 +08:00
@Sunyanzi 看大头传奇去了...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/164673

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX