PHP服務端支付寶app支付遇到的坑

咱們的項目用的php5.3 沒法使用支付寶提供的sdk 用新版的須要本身簽名驗籤 文檔中加了一句話進sdk參考裏面的函數自行簽名(你麻痹坑爹啊,草!)php

因此我選用了之前的移動支付 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最後拼接的 字符串中 裏面拼接了「」 也就是鍵對應的值應該加有雙引號 app

因此以前字符串拼接的時候 key 所對應的值 也應該有「」  咱們往上看 異步

//將post接收到的數組全部元素,按照「參數=參數值」的模式用「&」字符拼接成字符串。
    $data=createLinkstring($_POST);函數

拼接字符串 可是並無 把「」 拼接上  因此 從這裏獲得 加簽過得字符串  最後拼接的那幾個值 有「」工具

前面傳的值並無「」  這樣就可能請求失敗  而且官方文檔示例裏面值都拼接了「」  post

官方示例:

partner="2088101568358171"&seller_id="xxx@alipay.com
"&out_trade_no="0819145412-6177"&subject="測試"&body="測試測試"&total_fee="0.01"&notify_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 這個函數 由於 我是在服務端 完成了字符串拼接 因此 我把這個函數改了  如今咱們能夠把這個方法複製一份 從新起個名字 改過去從新調用一下 就能夠了 ,若是不是和我同樣把客戶端拼接作了,就不用改了。

此貼不經本人容許不得轉載!

相關文章
相關標籤/搜索