引子:
以下的部分代碼谬以、思路來自于 CSDN的一位博客主 泛领,以及 后宮 —— 易水 的支持拐揭。
1.前期申請流程介紹:
在微信開放平臺注冊賬戶:
- 注冊成功后在頂部菜單欄選擇管理中心--移動應(yīng)用--創(chuàng)建移動應(yīng)用[業(yè)主需要準(zhǔn)備應(yīng)用的官網(wǎng)(沒有可寫域名或者www.baidu.com[有未知風(fēng)險])颓芭、應(yīng)用的logo2張殖熟,一張28*28彻犁,一張108*108]
應(yīng)用創(chuàng)建完成之后申請開通微信支付接口:
- 在應(yīng)用詳情里叫胁,取得APPID;
- 開放平臺需進(jìn)行開發(fā)者資質(zhì)認(rèn)證后才可申請微信支付汞幢,認(rèn)證費(fèi):300元/次驼鹅;
- 認(rèn)證后進(jìn)行微信支付所需要的申請。[這里的申請需要提供APP應(yīng)用的信息,一般情況下均提供APP頁面截圖谤民,APP頁面截圖應(yīng)該包含:APP首頁堰酿、APP版權(quán)信息頁、APP商品展示頁张足、APP支付方式頁触创。另外需要特別注意自己的應(yīng)用是否涉及到了 網(wǎng)絡(luò)文化經(jīng)營許可證 的范疇,微信人工審核會判別這一點为牍,如果是需要提供此證哼绑。如申請不下這個證,則會有一定的法律風(fēng)險]
- 微信支付接口申請好之后碉咆,微信會向申請時填寫的郵箱發(fā)送微信商戶平臺賬戶信息抖韩;[賬戶、密碼疫铜、微信商戶號等]
在微信商戶平臺設(shè)置32位密鑰:
- [該網(wǎng)址的密碼框控件不支持谷歌瀏覽器]
- 用郵箱里的賬戶信息登錄茂浮,第一次登錄微信會提示設(shè)置防釣魚標(biāo)志,請牢記此值壳咕;
- Key設(shè)置路徑:微信商戶平臺--賬戶中心--API安全--API密鑰--密鑰設(shè)置[提供一個生成隨機(jī)碼的網(wǎng)頁]
其他說明:
- 在商戶平臺掃描首頁的二維碼席揽,關(guān)注支付提醒信息
- 微信提現(xiàn)有周期間隔,支付的金額不會實時轉(zhuǎn)到業(yè)主銀行賬戶上谓厘,需要人為轉(zhuǎn)出
- 以上加粗標(biāo)識的關(guān)鍵值均需業(yè)主提供給程序員幌羞,在代碼抒寫時有用到
2.支付流程示例:
商戶APP-----向商戶服務(wù)端發(fā)起請求--1--商戶服務(wù)端--2--向微信服務(wù)端發(fā)起請求得到唯一標(biāo)識--3--返回給商戶APP;
商戶APP根據(jù)返回值調(diào)起微信支付竟稳,消費(fèi)人支付成功属桦;
微信服務(wù)端-----4-----向商戶服務(wù)端發(fā)起請求,商戶服務(wù)端完成自身業(yè)務(wù)他爸;
其他:數(shù)字標(biāo)志的含義聂宾,1代表處理自身業(yè)務(wù),2代表按照微信要求請求微信诊笤,3按照微信要求解析返回值并同樣照要求返回APP亏吝,4代表按微信要求驗證參數(shù),完成自己業(yè)務(wù)盏混。
3.代碼結(jié)構(gòu)以及使用說明:
下載:
包含了微信支付和支付寶支付蔚鸥,密碼為phqa
結(jié)構(gòu):
使用說明:
- 操作者只需要填寫Config所需的信息,根據(jù)自身業(yè)務(wù)抒寫Controller许赃、service層即可止喷,其他結(jié)構(gòu)無需修改;在service里調(diào)用WxPayCore進(jìn)行微信必要的步驟即可混聊。
- WxPayConfig配置參數(shù)概覽:均為字符串
參數(shù)名 | 釋義或固定值 | 取得方式或固定值 |
---|---|---|
appid | 應(yīng)用id | 參考前期業(yè)主申請操作 |
mch_id | 微信商戶號 | 同上 |
key | 密鑰 | 同上 |
notify_url | 接收微信支付異步通知回調(diào)地址弹谁;通知url必須為直接可訪問的url,不能攜帶參數(shù) | 參考外網(wǎng)映射的配置方式https://www.ngrok.cc/ |
body | 商品描述交易字段 | APP名字-實際商品名稱比如:天天愛消除-游戲充值 |
以下值為固定值 | --- | --- |
spbill_create_ip | 客戶端ip地址 | 127.0.0.1[此值不影響] |
trade_type | 支付類型 | APP |
PACKAGE | --- | Sign=WXPay |
wxUrl | 微信統(tǒng)一下單接口請求地址 | https://api.mch.weixin.qq.com/pay/unifiedorder |
在Controller層抒寫兩個業(yè)務(wù),處理APP調(diào)起支付和微信的回調(diào)预愤;調(diào)起App的接口可以自定義參數(shù)沟于,接收微信的回調(diào)參數(shù)無需修改。在Service里抒寫自己的具體業(yè)務(wù)植康,然后調(diào)用固定方法進(jìn)行處理旷太。
eg:A用戶要購買100元的衣服,提供給App的接口需要接收用戶的id销睁,衣服的id供璧,在Service層里處理訂單的業(yè)務(wù)之后,調(diào)用WxPayCore.createWxPayParam(out_trade_no,total_fee)方法冻记,傳入商戶內(nèi)部訂單號和用戶所要支付的金額睡毒,并將返回值返給前端即可;
前端接收到返回值調(diào)起微信SDK冗栗,用戶支付完畢演顾;
微信會異步通知在Config里配置的回調(diào)地址,在回調(diào)的Service層里隅居,調(diào)用WxPayCore.checkWxPayParam(request)進(jìn)行驗證钠至,判斷是否是微信發(fā)送來的通知以及是否支付成功,返回值不為NULL即可進(jìn)行商品發(fā)貨或者填寫快遞訂單號等業(yè)務(wù)军浆。兩個核心方法使用介紹:
1.SortedMap<Object, Object> wxAppparameters = WxPayCore.createWxPayParam(String out_trade_no,String total_fee);
a)拼接微信支付必要參數(shù),加簽挡闰,并返回Map對象乒融;
b)out_trade_no 傳入商戶內(nèi)部訂單號,必須唯一摄悯;total_fee 所要支付的金額赞季,格式必須為0.00,單位為元奢驯;
c)返回App端調(diào)起支付所需要的參數(shù)申钩。
2.SortedMap<Object, Object> parameters = WxPayCore.checkWxPayParam(request);
a)支付成功的回調(diào):檢測微信異步反饋是否真實,不為null為真實瘪阁,null為校驗失敗撒遣。
b)返回的map中可以取得微信返回的參數(shù),一般只取out_trade_no(商戶內(nèi)部訂單號)管跺、total_fee(充值的金額,單位為分)义黎、transaction_id(微信支付訂單號)。
c)判斷parameters是否不為NULL豁跑,不為NULL拿商戶內(nèi)部訂單號去查出充值的訂單數(shù)據(jù)廉涕,完成自己的業(yè)務(wù)。
- 特別注意:在處理的回調(diào)里,處理成功后需要向微信反饋成功:
Eg:out.print(HttpXmlUtil.backWeixin("SUCCESS","OK")); *
如果處理失敗則無需反饋狐蜕;微信如果接收不到正確反饋宠纯,則會按照一定策略重復(fù)通知,代碼中應(yīng)該有去重處理[判斷該訂單是否已經(jīng)處理過*]
注意事項:
- WxPayCore類里的方法均不需要修改层释,和業(yè)務(wù)無關(guān)婆瓜,直接調(diào)用即可。
引用jar:
- dom4j-1.6.1.jar
- jdom.jar
- 微信不提供sdk湃累,上述jar包無需修改勃救。
4.備注以及拓展:
文檔的第一步驟可以截取發(fā)給業(yè)主參考申請,讓業(yè)主提供加粗的參數(shù)信息治力;
- 本著程序員應(yīng)全身心在開發(fā)上蒙秒,避免不必要的時間浪費(fèi)。
對WxPayCore.createWxPayParam()方法的解釋:
- 方法的作用就是按照微信的要求去請求微信并得到唯一的標(biāo)識并返回給APP端宵统;App端根據(jù)此返回值調(diào)起微信[微信所需要的是很多參數(shù)晕讲,不是字符串形式的];
- 返回的參數(shù)里包含著調(diào)起支付的唯一標(biāo)識马澈,[微信要扣多少錢瓢省、微信服務(wù)端給哪個地址發(fā)送支付成功的通知等信息都保存在 微信的服務(wù)端 了:通過服務(wù)端請求微信的那次請求,稱作 統(tǒng)一下單接口]痊班;
- 請求微信的規(guī)則是[微信簽名的規(guī)則]:
1.將參數(shù)的key值按照ascii碼的順序進(jìn)行排序勤婚,并轉(zhuǎn)化成key=value&key=value的形式;
2.拼接完所有的非sign參數(shù)后涤伐,字符串末尾拼入key=32位字符串[上面提及的key值]然后進(jìn)行MD5加密并轉(zhuǎn)為大寫馒胆,得到sign值; - 微信以上的2步是為了確保這個通知是商戶的自身發(fā)送出來的凝果,拿key參與MD5運(yùn)算祝迂,確保唯一性。[如果微信不這么做器净,訂單信息被別人篡改了型雳,對雙方都將是最壞的結(jié)果];
- 微信請求以及返回值的形式都是xml形式山害,服務(wù)端請求微信前將map的值轉(zhuǎn)為xml發(fā)送請求[發(fā)送了這個請求就意味著微信服務(wù)端存儲了該訂單的信息]纠俭,得到返回值解析出來,得到預(yù)支付訂單[唯一性的東西]浪慌,再按照微信調(diào)起支付的參數(shù)要求繼續(xù)拼接柑晒,并用MD5生成sign字段;
對WxPayCore.checkWxPayParam()方法的解釋:
- 方法的作用就是檢測是否是微信發(fā)送來的通知眷射,根據(jù)此通知進(jìn)行支付成功的業(yè)務(wù)匙赞;
- 微信是不會發(fā)送支付失敗的通知的佛掖;
- 驗證也有相應(yīng)的規(guī)則:
1.將微信的參數(shù)都取出[這里有個拓展,requesr.getParameterMap()就可以取出Map形式的參數(shù)]涌庭;
2.取出sign字段芥被,將剩余參數(shù)變成按照ascii碼排序的key=value&形式再次進(jìn)行加簽;
3.自己加簽的簽名和取出的sign字段進(jìn)行比較坐榆,查看是否一致拴魄; - 同理,微信需要這樣的驗證步驟席镀,也是為了確保該通知是微信發(fā)出的匹中,以防別人冒發(fā)送請求;
- 為防止意外豪诲,對訂單號顶捷、商戶的基本信息做驗證。
拓展:
- 關(guān)于數(shù)字簽名這里有一篇文章介紹的很全面:
- 將參數(shù)拼接密鑰進(jìn)行加簽屎篱,接收者根據(jù)參數(shù)同樣進(jìn)行加簽服赎,驗證自己所加的簽名與發(fā)送者的是否一致,來達(dá)到信息的準(zhǔn)確性交播;
- 也推薦關(guān)注該文章的翻譯者:阮一峰重虑。