前言
在APP中接入微信支付其實(shí)很簡(jiǎn)單,大部分工作主要都是后臺(tái)完成桐筏,客戶端只需要調(diào)用后臺(tái)拇砰,得到后臺(tái)返回的字符串后在調(diào)用微信的api即可。但是會(huì)有些坑牧氮,稍不注意就會(huì)掉坑里瑰枫,下面會(huì)講到。
一. 接入流程
- 在微信開發(fā)平臺(tái)上有詳細(xì)介紹尸诽,這個(gè)就不多說(shuō)了盯另。
- 交互時(shí)序圖
商戶系統(tǒng)和微信支付系統(tǒng)主要交互說(shuō)明:
- 用戶在商戶APP中選擇商品,提交訂單商蕴,選擇微信支付芝发。
- 商戶后臺(tái)收到用戶支付單,調(diào)用微信支付統(tǒng)一下單接口(后臺(tái)處理部宿,客戶端不需要做)
- 統(tǒng)一下單接口返回正常的prepay_id瓢湃,再按簽名規(guī)范重新生成簽名后赫蛇,將數(shù)據(jù)傳輸給APP。參與簽名的字段名為appId落蝙,partnerId,prepayId筏勒,nonceStr管行,timeStamp,package捐顷。注意:package的值格式為Sign=WXPay 》显蓿客戶端拿到這些字段后就可以發(fā)起支付了叮姑。
二. APP端開發(fā)步驟
- 導(dǎo)入sdk包。微信支付sdk包
- 在調(diào)用api之前需要向微信注冊(cè)你的appid耘沼,代碼如下:
{ IWXAPI api; api= WXAPIFactory.createWXAPI(this, null); IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
//xxx為你的appid
msgApi.registerApp("xxx");}
- 調(diào)用微信api
調(diào)后臺(tái)接口旷祸,將后臺(tái)返回的字段做如下處理:
{ PayReq req = new PayReq();
req.packageValue = "package"; req.sign = "sign"; req.timeStamp = "timestamp"; req.appId = "appid"; req.nonceStr = "noncestr"; req.partnerId = "partnerid"; req.prepayId = "prepayid"; api.sendReq(req); }
這些字段最好是在后臺(tái)獲取托享,不要放在本地。 - 在AndroidManifest.xml中配置以下權(quán)限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
開發(fā)者可參考 微信支付官方demo - 支付結(jié)果回調(diào)
參照微信支付demo赃绊,在net.sourceforge.simcpux.wxapi包路徑中實(shí)現(xiàn) WXPayEntryActivity類(包名或類名不一致會(huì)造成無(wú)法回調(diào))羡榴,在WXPayEntryActivity類中實(shí)現(xiàn)onResp函數(shù),支付完成后校仑,微信APP會(huì)返回到商戶APP并回調(diào)onResp函數(shù)迄沫,開發(fā)者需要在該函數(shù)中接收通知,判斷返回錯(cuò)誤碼羊瘩,如果支付成功則去后臺(tái)查詢支付結(jié)果再展示用戶實(shí)際支付結(jié)果。注意一定不能以客戶端返回作為用戶支付的結(jié)果逝她,應(yīng)以服務(wù)器端的接收的支付通知或查詢API返回的結(jié)果為準(zhǔn)。代碼示例如下:
publicvoidonResp(BaseRespresp){ if(resp.getType()==ConstantsAPI.COMMAND_PAY_BY_WX){ Log.d(TAG,"onPayFinish,errCode="+resp.errCode); AlertDialog.Builderbuilder=newAlertDialog.Builder(this); builder.setTitle(R.string.app_tip); }
然后在配置文件中注冊(cè)WXPayEntryActivity
<activity android:name=".wxapi.WXPayEntryActivity" android:label="@string/app_name" android:exported="true" android:launchMode= "singleTop" />
返回值:
0 :成功
-1 :失敗近刘,可能原因:簽名錯(cuò)誤宁昭、未注冊(cè)APPID、項(xiàng)目設(shè)置APPID不正確疆拘、注冊(cè)的APPID與設(shè)置的不匹配寂曹、其他異常等。
-2 :用戶取消漱挚,無(wú)需處理渺氧。發(fā)生場(chǎng)景:用戶不支付了,點(diǎn)擊取消白华,返回APP贩耐。
三. 開發(fā)中所遇到的問題
- 回調(diào)結(jié)果返回-1,首先檢查appid是否正確管搪,然后就是簽名問題了铡买,app的簽名必須是正式打包好的簽名,而且必須和微信開放平臺(tái)填的一樣奇钞。
應(yīng)用簽名的keystore要固定蛇券,否則簽名會(huì)不一樣。
安裝打包好的apk就可以調(diào)用微信了塘慕,但是在編譯器run的時(shí)候卻又還是返回-1蒂胞,這是因?yàn)榫幾g器run的是debug版的簽名,和正式的不一樣當(dāng)然會(huì)錯(cuò)了蛤织,但是每次調(diào)試都要打包一次嗎鸿染?這豈不是很麻煩...其實(shí)只要在build.gradle配置幾行代碼即可搞定:
signingConfigs{ release{storeFile file("C:/Users/dell/Desktop/xxx.jks") //該路徑為keystore的保存路徑 //以下3個(gè)根據(jù)你的keystore自行配置 storePassword "xxx" keyAlias "xxx" keyPassword "xxx"}
buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'} debug{ signingConfig signingConfigs.release}
這樣一來(lái)就可直接run了,非常方便調(diào)試
2 回調(diào)類名和包名
- 回調(diào)類名必須是WXPayEntryActivity摊鸡,而且在該類中要實(shí)現(xiàn)IWXAPIEventHandler接口
- 包名必須是你app包名+wxapi蚕冬。例如com.test.main.wxapi
- WXPayEntryActivity必須放到該路徑下。
- 如果與上述條件不一致很可能造成支付后無(wú)法回調(diào)猎提。如果你不想回調(diào)旁蔼,那么上述包名和類名可不創(chuàng)建,微信支付后會(huì)默認(rèn)返回當(dāng)前支付頁(yè)面蚓炬。如果想要支付成功后跳轉(zhuǎn)到別的頁(yè)面(例如訂單頁(yè))躺屁,那么則要?jiǎng)?chuàng)建。