咱們的項目用的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"¬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 這個函數 由於 我是在服務端 完成了字符串拼接 因此 我把這個函數改了 如今咱們能夠把這個方法複製一份 從新起個名字 改過去從新調用一下 就能夠了 ,若是不是和我同樣把客戶端拼接作了,就不用改了。
此貼不經本人容許不得轉載!