我们的项目用的php5.3 无法使用支付宝提供的sdk 用新版的需要自己签名验签 文档中加了一句话进sdk参考里面的函数自行签名(你麻痹坑爹啊,草!)
所以我选用了以前的移动支付 demo下载链接
https://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1
第一个坑:
其中PHP demo 里signatures_url.php文件中
//确认PID和接口名称是否匹配。
date_default_timezone_set("PRC");
if (str_replace('"','',$_POST['partner'])==$alipay_config['partner']&&str_replace('"','',$_POST['service'])==$alipay_config['service']) {
//将post接收到的数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串。
$data=createLinkstring($_POST);
//打印待签名字符串。工程目录下的log文件夹中的log.txt。
logResult($data);
//将待签名字符串使用私钥签名,且做urlencode. 注意:请求到支付宝只需要做一次urlencode.
//$rsa_sign=urlencode(rsaSign($data, $alipay_config['private_key']));
$rsa_sign=rsaSign($data, $alipay_config['private_key']);
$rsa_sign = urlencode(mb_convert_encoding($rsa_sign, "UTF-8"));
//把签名得到的sign和签名类型sign_type拼接在待签名字符串后面。
$data = $data.'&sign='.'"'.$rsa_sign.'"'.'&sign_type='.'"'.$alipay_config['sign_type'].'"';
//返回给客户端,建议在客户端使用私钥对应的公钥做一次验签,保证不是他人传输。
//echo $data;
看里面$data最后拼接的 字符串中 里面拼接了“” 也就是键对应的值应该加有双引号
所以之前字符串拼接的时候 key 所对应的值 也应该有“” 我们往上看
//将post接收到的数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串。
$data=createLinkstring($_POST);
拼接字符串 但是并没有 把“” 拼接上 所以 从这里得到 加签过得字符串 最后拼接的那几个值 有“”
前面传的值并没有“” 这样就可能请求失败 并且官方文档示例里面值都拼接了“”
官方示例:
partner="2088101568358171"&seller_id="xxx@alipay.com
"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"¬ify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay=
"30m"&sign="lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJIe2pbjm%2F3kb%2FuGkpG%2BwYQYI51%2BhA3YBbvZHVQBYveBqK%2Bh8mUyb7GM1HxWs9k4%3D"&sign_type="RSA"
我们打开lib下的alipay_core.function.php 找到
/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
* @param $para 需要拼接的数组
* return 拼接完成以后的字符串
*/
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;
}
发现这个函数并没有再$val 两边拼接上“” 此处我做了修改 我的代码
/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
* @param $para 需要拼接的数组
* return 拼接完成以后的字符串
*/
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;
}
经过测试 得到的字符串可以用了
这是demo的bug 我已经提交给支付宝技术了 如图
第二个坑
app 支付 密钥生成工具一定要用这个 https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7386797.0.0.blDCGK&treeId=291&articleId=106097&docType=1 这个是V1.3版本的
我之前用的老版本的密钥生成工具V1.0 app 支付测试怎么都不行 为了验证密钥是匹配的 我下了一个即时到账demo RSA 版的 配置了支付宝公钥 和开发者私钥 测试成功了 说明 秘钥是匹配的 但是app 支付还是不行 之后我用V1.3版本的密钥生成器 重新配置了一下 靠! 可以了 太坑了 写个博客记下来
顺便说一下 app 支付 其本上全都是做后端的跟支付宝服务器做交互 比如加签发送字符串 验签异步回调从而改变订单状态等 前端只需要调用支付宝客户端就行了
此贴不经本人允许不得转载!
2017 1 9 更新
感谢支付宝的技术人员 回复我
主要意思是 那个函数 是接受 客户端 拼接好的字符串 而我把客户端的活也给干了,我们这客户端只需要把订单号传过来,之后的拼接也放在了服务端完成。如果不改demo 里的方法,就需要客户端来进行字符串拼接,拼接完之后服务端接受拼接完的字符串,进行加签,完了传给客户端。
支付成功以后 需要验签 验签的时候 需要用到getSignVeryfy 方法 而在这个方法里 有一个 字符串拼接函数
createLinkstring 这个函数 因为 我是在服务端 完成了字符串拼接 所以 我把这个函数改了 现在我们可以把这个方法复制一份 重新起个名字 改过去重新调用一下 就可以了 ,如果不是和我一样把客户端拼接做了,就不用改了。
此贴不经本人允许不得转载!