官方解決方案:
可參考以下指引:
https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay7_1.shtml#part-2
當使用V3接口報簽名類錯誤,還有在對返回的信息做驗簽,如:回調(diào)通知驗簽,驗簽失敗的錯誤,都可以使用驗簽工具驗簽,本文主要介紹如何正確使用簽名工具,以及簽名工具能排查出的幾種原因。
工具下載、使用:
1.首先先下載官方提供的驗簽工具:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml#part-1
2.下載解壓后打開文件夾,里面有我們的驗簽工具、錯誤碼對照表和使用說明書,TenpayCertUtil.exe就是驗簽工具了,雙擊打開
3.工具界面:
一共三個部分:
1、選擇文件:
校驗自己請求接口生成的簽名,使用在商戶平臺下載的商戶證書文件,建議使用其中具體的商戶私鑰文件,apiclient_key.pem文件(這個是默認的文件名,如果有下載后自己改過,就按自己改的選,只要是正確的商戶私鑰文件就行),因為使用這個文件,既可以用工具驗簽自己的簽名,又可以用工具直接生成簽名值。商戶證書獲?。?a target="_blank">https://kf.qq.com/faq/161222NneAJf161222U7fARv.html
校驗接口應(yīng)答的簽名值,如:回調(diào)通知的驗簽,就要使用平臺證書驗簽,所以要先獲取平臺證書:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay5_1.shtml
2、明文:
這里要填放的是生成簽名或驗簽時構(gòu)造的簽名串/驗簽串,注意不是已經(jīng)生成好的簽名值
簽名串:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_0.shtml#part-1
驗簽串:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_1.shtml#part-2
3、簽名
這里要填放的就是要校驗的簽名值,如果是要直接對簽名串進行簽名,而不是要校驗簽名,可以不填寫此處,然后點擊下方的簽名按鈕,工具會將生成的簽名值顯示在此處,可以用工具生成的簽名值和自己代碼中生成的簽名值進行對比,看是否一致。
驗簽排查思路:
了解了驗簽工具要填寫的三個部分后,就可以開始驗簽了,下面我會舉例幾種工具可以排查出來的情況,或配合工具可以排查出來的情況,為了不泄露信息,我會用官網(wǎng)示例這樣的中文代替實際數(shù)值
先放三個正確驗簽的明文示例,點擊驗簽,后面的示例圖主要放的是對自己生成的簽名值校驗的示例圖:
此處注意應(yīng)答簽名的驗簽使用的是平臺證書驗簽,而不是使用商戶證書,所以第一步選擇的文件要選擇平臺證書文件
平臺證書的獲取:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay5_1.shtml
情景一:如果按正確驗簽示例填寫的方式:驗簽不通過,說明這個簽名值與這個簽名串是不匹配的,建議按文章開頭提供的官方解決方案檢查下,也可以嘗試下面情景二、三的明文方式,看看是否碰巧:驗簽通過
情景二:
如上方式填寫明文:驗簽通過,說明程序中,在構(gòu)造簽名串時,最后一行沒有加上換行
情景三:
如上方式填寫明文:驗簽通過,說明程序中,在構(gòu)造簽名串時,將換行符 \n 作為字符串"\n"去構(gòu)造簽名串/驗簽串的,而不是作為轉(zhuǎn)義字符 \n 去構(gòu)造簽名串/驗簽串的
情景四:如果按正確驗簽示例填寫的方式:驗簽通過,就需要更加仔細的檢查下自己的代碼:
1.可能使用錯了一個商戶私鑰/平臺證書
這個不是指代碼里用的和工具用的不是同一個,而是指比如本來要使用A商戶的商戶私鑰/平臺證書,但實際使用的是B商戶的
2.可能代碼中實際編碼存在問題
將所有中文部分換成英文,如果這時請求通過,說明是編碼問題
3.可能簽名串中的參數(shù),和實際請求的參數(shù)不一致,不能增加或缺少參數(shù),參數(shù)大小寫要與文檔一致(可通過打印簽名原串進行排查)
如請求頭中的時間戳、隨機字符串和簽名串的不一致,具體請參考文章開頭提供的官方解決方案
4.可能簽名串/驗簽串、簽名值在數(shù)值傳遞過程中,發(fā)生了改變
在代碼實際填寫簽名值時,可能在各種方法傳遞中去除了'=',或?qū)⒁恍┓栕隽似渌D(zhuǎn)換,如'+'被替換成' '(空格),然后被添加到請求頭,或用來應(yīng)答驗簽,所以工具通過,代碼報錯。'+'替換成' '在網(wǎng)絡(luò)上有相應(yīng)的解決方案,可自行查找下。
注:如果不確定簽名值是否在傳值過程中被處理修改,可以在工具中不填寫簽名值,點擊簽名按鈕,將生成好的簽名值直接放進請求頭,時間戳、隨機字符串也是,都寫成固定值,如果通過請求,則說明在之前傳值過程中,數(shù)據(jù)有被修改,須仔細排查
情景五:如果是下單成功,調(diào)起支付時報錯,按正確驗簽示例填寫的方式:驗簽通過,則需要前后端同學(xué)一起配合檢查
1.傳給前端接收到的調(diào)起時所用的數(shù)據(jù),是否和后端生成的簽名值所使用的簽名串中數(shù)據(jù)一致
例如:時間戳、隨機字符串等,可以由前端打印出調(diào)起支付時實際使用數(shù)據(jù),組成簽名串,進行驗簽,看看驗簽是否通過,如果后端驗簽通過,而前端使用調(diào)起支付的數(shù)據(jù)做簽名串驗簽不通過,則說明前端調(diào)起使用的數(shù)據(jù)與后端生成簽名值使用的數(shù)據(jù)不一致
2.前端調(diào)起支付時填寫的參數(shù)是否有一一對應(yīng)
例如:timeStamp的值錯填了隨機字符串,nonceStr的值錯填了時間戳
3.前端調(diào)起支付時填寫的參數(shù)名、參數(shù)值是否正確,要注意參數(shù)名的大小寫,參數(shù)值一定要正確填寫
例如:signType的值為'RSA',不要錯填'RAS',package的值不要忘記加上'prepay_id='
4.調(diào)起支付時生成簽名使用的商戶私鑰和下單時生成簽名使用的不是同一個商戶私鑰
這個可以用下單時的簽名串、簽名值和這個調(diào)起支付簽名使用的私鑰文件驗簽一下,如果通過則說明下單和調(diào)起的簽名用的是同一個私鑰文件,沒有使用錯誤,如果不通過,說明調(diào)起支付時使用的商戶私鑰是錯誤的,需要檢查
情景六:校驗應(yīng)答簽名時,校驗總是報錯,比如回調(diào)通知驗簽,建議檢查下應(yīng)答報文主體中,各個參數(shù)的順序,一定要原樣按照通知的順序去構(gòu)造驗簽串
如微信通知的是{C,B,A},就要按{C,B,A}原樣填寫,注意不要在轉(zhuǎn)JSON格式時,或其他傳值過程中進行排序,變成了{A,B,C},這樣構(gòu)造的驗簽串是肯定驗簽不通過的
明文中{C,B,A}要寫成一行的形式,不要按JSON去換行寫成:
正確示例:
以上是我個人總結(jié)的一些V3校驗簽名工具的使用,和排除查思路,如果有需要補充或修改的地方,歡迎留言反饋
另補充下:判斷商戶私鑰、商戶號、商戶證書序列號是否匹配,可以用官方提供的postman腳本去校驗下的,如果postman腳本也是報簽名錯誤,說明這三個是不匹配的,要檢查,還有就是官方的postman腳本是V3的簽名規(guī)則來的,V3的簽名規(guī)則和V2的簽名規(guī)則是不一樣的
postman腳本:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay6_0.shtml#part-1