摘要:微信支付支付在服務(wù)端調(diào)用統(tǒng)一下單接口后,服務(wù)端需要將返回的訂單數(shù)據(jù)進(jìn)行二次簽名后才能返回給端。微信支付服務(wù)端提供了類,類中也的確提供了生成簽名方法,即對結(jié)果集簽名,源碼如下以版為例,其他語言自行對照。
獲取到 prepay_id 后將參數(shù)再次簽名傳輸給 APP 發(fā)起支付。
相信有不少同學(xué)因?yàn)榭吹浇y(tǒng)一下單返回的結(jié)果中有 sign 字段,會直接將結(jié)果返回給 APP 端,結(jié)果 APP 端沒辦法調(diào)起微支付。其實(shí)需要對 APP 端用到的字段數(shù)據(jù)按 “統(tǒng)一下單的簽名方式” 簽名后得到的 sign,才是 APP 端需要的 sign。
微信支付 App支付 在服務(wù)端調(diào)用統(tǒng)一下單接口后,服務(wù)端需要將返回的訂單數(shù)據(jù)進(jìn)行二次簽名后才能返回給 App 端。開發(fā)文檔中說的并不是很明確,因?yàn)榻y(tǒng)一下單的返回?cái)?shù)據(jù)和二簽的原數(shù)據(jù)上存在一些重疊。
微信支付服務(wù)端 sdk 提供了 WxPayResults 類,類中也的確提供了生成簽名方法,即對結(jié)果集簽名,源碼如下:
以 PHP 版為例,其他語言自行對照。
class WxPayResults extends WxPayDataBase { /** * 生成簽名 - 重寫該方法 * @param WxPayConfigInterface $config 配置對象 * @param bool $needSignType 是否需要補(bǔ)signtype * @return 簽名,本函數(shù)不覆蓋sign成員變量,如要設(shè)置簽名需要調(diào)用SetSign方法賦值 */ public function MakeSign($config, $needSignType = false) { //簽名步驟一:按字典序排序參數(shù) ksort($this->values); $string = $this->ToUrlParams(); //簽名步驟二:在string后加入KEY $string = $string . "&key=" . $config->GetKey(); //簽名步驟三:MD5加密或者HMAC-SHA256 if (strlen($this->GetSign()) <= 32) { //如果簽名小于等于32個,則使用md5驗(yàn)證 $string = md5($string); } else { //是用sha256校驗(yàn) $string = hash_hmac("sha256", $string, $config->GetKey()); } //簽名步驟四:所有字符轉(zhuǎn)為大寫 $result = strtoupper($string); return $result; } }
注意步驟三,是需要獲取 sign 來判斷使用什么方式生成 sign 的,是不是有種雞生蛋,蛋生雞的短路既視感。在 APP 端調(diào)起支付的參數(shù)列表的 sign 參數(shù)里有提示 “注意:簽名方式一定要與統(tǒng)一下單接口使用的一致”,所以這里的邏輯是要你將統(tǒng)一下單返回的 sign 傳遞進(jìn)來,以便于統(tǒng)一簽名方式。簽名后一定要用真的簽名去覆蓋用來傳遞簽名方式的“簽名”。
在統(tǒng)一下單接口中,生成簽名的流程是 $obj->setSign() 調(diào)用 $obj->makeSign(),而后我們可以 $obj->getSign() 將簽名加到請求數(shù)據(jù)中。但在結(jié)果集類中,makeSign 卻直接調(diào)用了 getSign 來判斷使用何種方式生成簽名,所以對結(jié)果集簽名時(shí),需確保結(jié)果集中包含了同一下單返回的 sign 字段數(shù)據(jù),這樣結(jié)果集才能滿足 “注意:簽名方式一定要與統(tǒng)一下單接口使用的一致” 的要求。
所以這個類對簽名進(jìn)行了重寫的目的,主要是為了保證二次簽名的簽名方式與統(tǒng)一下訂單的簽名方式一致,將統(tǒng)一下單的簽名作為 sign 傳遞給
WxPayResults 然后調(diào)用 makeSign,makeSign 就能判斷出統(tǒng)一下單的簽名方式,與之保持一致。
$uniorder = array ( "appid" => "wxd930ea5d5a258f4f",//appid "device_info" => "WEB", "mch_id" => "1900000109",// 商戶id "nonce_str" => "g6OZoULWyliPmiPm", "prepay_id" => "wx12143635206473d0a53e80f14278847815", "result_code" => "SUCCESS", "return_code" => "SUCCESS", "return_msg" => "OK", "sign" => "E91035CA24EDF115374BD2B4C4F9B419",//統(tǒng)一下單的簽名 "trade_type" => "APP", )服務(wù)端需要二簽的數(shù)據(jù)
文檔地址:https://pay.weixin.qq.com/wik...
package 暫填寫固定值Sign=WXPay
noncestr 并不一定要統(tǒng)一下單返回的 nonce_str,自己生成 32位 的也可以
timestamp 自己生成即可
sign 傳遞統(tǒng)一下單返回的簽名,以使得結(jié)果集簽名和統(tǒng)一下單簽名方式一致(或者你清楚的知道你對結(jié)果集簽名的方式同下單的一致)
如果自己寫,二不用 sdk 的話,我們需要對
$uniorder["appid"],//從統(tǒng)一下單的結(jié)果中取 "partnerid" => $uniorder["mch_id"],//從統(tǒng)一下單的結(jié)果中取 "prepayid" => $uniorder["prepay_id"],//從統(tǒng)一下單的結(jié)果中取 "package" => "Sign=WXPay",//自己寫 "noncestr" => WxPayApi::getNonceStr();,//自己寫 "timestamp " => time(),//自己寫 ); // 與統(tǒng)一下單的簽名方式一致即可 $sign = signMethodConsistWithUniOrder($app_result); $app_result["sign"] = $sign; // 返回給 APP 端 return $$app_result;
如果用 sdk 的務(wù)必要將 統(tǒng)一下單返回的數(shù)據(jù)里的簽名 sign 也傳遞給 WxPayResults 類,已使得保證簽名方式一致
$uniorder["appid"],//從統(tǒng)一下單的結(jié)果中取 "partnerid" => $uniorder["mch_id"],//從統(tǒng)一下單的結(jié)果中取 "prepayid" => $uniorder["prepay_id"],//從統(tǒng)一下單的結(jié)果中取 "sign" => $uniorder["sign"],//用來使結(jié)果集簽名方式與統(tǒng)一下單簽名方式一致 "package" => "Sign=WXPay",//自己寫 "noncestr" => WxPayApi::getNonceStr();,//自己寫 "timestamp " => time(),//自己寫 ); $wxPayResults = new WxPayResults(); // 構(gòu)建 WxPayResults 對象 $wxPayResults->FromArray($app_result); // 真正的返回?cái)?shù)據(jù)的簽名 覆蓋用來統(tǒng)一簽名方式的“簽名” $app_result["sign"] = $wxPayResults->makeSign($wxPayConfig);//然后更新成二簽后的sign // 返回給 APP 端 return $$app_result;App 端調(diào)用微信支付的方式為
IWXAPI api; PayReq request = new PayReq(); request.appId = "wxd930ea5d5a258f4f"; request.partnerId = "1900000109"; request.prepayId= "1101000000140415649af9fc314aa427",; request.packageValue = "Sign=WXPay"; request.nonceStr= "1101000000140429eb40476f8896f4c9"; request.timeStamp= "1398746574"; request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B"; api.sendReq(request);
使用服務(wù)端提供的數(shù)據(jù)發(fā)起支付請求即可。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/29953.html
摘要:這是我第一次接觸微信支付,發(fā)現(xiàn)網(wǎng)上還是有很多同學(xué)在求助,了怎么辦是什么情況為了幫助更多的小伙伴脫離苦海,我決定寫下這次的踩坑之旅,給更多的人幫助。 凡是和錢打交道的事,沒有一樣是容易的。這是我第一次接觸微信支付,發(fā)現(xiàn)網(wǎng)上還是有很多同學(xué)在求助,XXX了怎么辦?XXX是什么情況?為了幫助更多的小伙伴脫離苦海,我決定寫下這次的踩坑之旅,給更多的人幫助。 介紹 微信支付方式分為刷卡支付、公眾號...
摘要:這是我第一次接觸微信支付,發(fā)現(xiàn)網(wǎng)上還是有很多同學(xué)在求助,了怎么辦是什么情況為了幫助更多的小伙伴脫離苦海,我決定寫下這次的踩坑之旅,給更多的人幫助。 凡是和錢打交道的事,沒有一樣是容易的。這是我第一次接觸微信支付,發(fā)現(xiàn)網(wǎng)上還是有很多同學(xué)在求助,XXX了怎么辦?XXX是什么情況?為了幫助更多的小伙伴脫離苦海,我決定寫下這次的踩坑之旅,給更多的人幫助。 介紹 微信支付方式分為刷卡支付、公眾號...
摘要:前言最近應(yīng)公司業(yè)務(wù)需求,把微信支付完成了,當(dāng)然已經(jīng)順利上線。第三步查詢訂單該接口提供所有微信支付訂單的查詢,商戶可以通過該接口主動查詢訂單狀態(tài),完成下一步的業(yè)務(wù)邏輯。 前言 最近應(yīng)公司業(yè)務(wù)需求,把微信支付完成了,當(dāng)然已經(jīng)順利上線。但是開發(fā)的過程是也是踩了很多坑,下面我就先說說開發(fā)流程,以及在開發(fā)中遇到的大大小小的坑。 開發(fā)流程 首先,看一下微信開方平臺關(guān)于支付的一個時(shí)序圖,如下: sh...
摘要:前者集成在中,后者主要是為微信用戶提供了另一種支付方式需要在微信的內(nèi)置瀏覽器中打開頁面,再調(diào)起微信支付。步驟商戶后臺收到用戶支付單,調(diào)用微信支付統(tǒng)一下單接口。拿到所有參數(shù)后,就可以在頁面中發(fā)起微信支付的請求了。 微信支付,支持的支付方式比較多:有掃碼支付,刷卡支付,APP支付和公眾號支付。其中,APP和網(wǎng)站上最常用的就是APP支付和公眾號支付。前者集成在APP中,后者主要是為微信用戶提...
摘要:附微信支付流程微信支付流程和小程序的支付流程基本一致,需要注意兩點(diǎn)需要在微信商戶平臺配置支付目錄,只有跳轉(zhuǎn)到了支付目錄的地址,才能發(fā)起微信支付。 我所在公司需要開發(fā)一款商城小程序,里面需要用到微信支付,我負(fù)責(zé)里面的下單功能,從小程序端到后臺的支付流程都是我自己開發(fā)的,由于我們組沒有人有開發(fā)微信支付的經(jīng)驗(yàn),很多東西都還不怎么明白,但是沒辦法,只能我自己琢磨,寫完之后總感覺有bug,但是不...
閱讀 2082·2019-08-30 15:53
閱讀 3076·2019-08-30 15:44
閱讀 2927·2019-08-30 14:11
閱讀 2922·2019-08-30 14:01
閱讀 2710·2019-08-29 15:16
閱讀 3762·2019-08-29 13:10
閱讀 1255·2019-08-29 10:56
閱讀 2538·2019-08-26 13:58