PHP服务端支付宝app支付遇到的坑

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

我们的项目用的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="[email protected]
"&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 我已经提交给支付宝技术了 如图

PHP服务端支付宝app支付遇到的坑_第1张图片

第二个坑  

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 这个函数 因为 我是在服务端 完成了字符串拼接 所以 我把这个函数改了  现在我们可以把这个方法复制一份 重新起个名字 改过去重新调用一下 就可以了 ,如果不是和我一样把客户端拼接做了,就不用改了。

此贴不经本人允许不得转载!

 

转载于:https://my.oschina.net/hfframework/blog/819244

你可能感兴趣的:(PHP服务端支付宝app支付遇到的坑)