一:介紹
專案中要用到支付功能,需要支付寶支付、微信支付、銀聯支付,所以打算總結一下,方便以後的查閱,也方便大家, 用到的地方避免再次被坑。 今天我們就主要介紹一下微信支付,其他支付也寫了對應教程,並且給出了連線。
整合前首先要看看文件,微信支付開發文件裡面有詳細的欄位和說明。 微信支付是需要簽名的,跟支付寶一樣,可以在客戶端簽名,也可以在後臺簽名(當然,為了安全還是推薦在伺服器上做簽名,邏輯也比較好理解)
二:業務流程
以下是互動時序圖,統一下單API、支付結果通知API和查詢訂單API等都涉及簽名過程,呼叫都必須在商戶伺服器端完成。
商戶系統和微信支付系統主要互動說明:
-
- 使用者在商戶APP中選擇商品,提交訂單,選擇微信支付。
-
- 商戶後臺收到使用者支付單,呼叫微信支付統一下單介面。
-
- 統一下單介面返回正常的prepay_id,再按簽名規範重新生成簽名後,將資料傳輸給APP。參與簽名的欄位名為appid,partnerid,prepayid,noncestr,timestamp,package。
-
- 商戶APP調起微信支付。
-
- 商戶後臺接收支付通知。
-
- 商戶後臺查詢支付結果。
三:下載微信SDK
微信開放平臺下載SDK 建議把Android標頭檔案和支付示例都下載下來
四:後臺設定
商戶在微信開放平臺申請開發應用後,微信開放平臺會生成APP的唯一標識APPID。由於需要保證支付安全,需要在開放平臺繫結商戶應用包名和應用簽名,設定好後才能正常發起支付。設定介面在【開放平臺】中的欄目【管理中心 / 修改應用 / 修改開發資訊】裡面。如下圖:
應用包名:是在APP專案配置檔案AndroidManifest.xml中宣告的package值,例如DEMO中的。
package="net.sourceforge.simcpux"
複製程式碼
應用簽名:根據專案的應用包名和編譯使用的keystore,可由簽名工具生成一個32位的md5串,在除錯的手機上安裝簽名工具後,執行可生成應用簽名串,如下圖所示,綠色串即應用簽名。
簽名工具下載地址
open.weixin.qq.com/zh_CN/htmle…
net.sourceforge.simcpux 是專案包名
五:匯入開發SDK
匯入sdk流程同支付寶匯入流程一樣,這裡就借用支付寶匯入流程進行介紹。
5.1 如果專案開發使用的Eclipse軟體,匯入步驟如下:
1.將alipaySDK-20150602.jar包放入商戶應用工程的libs目錄下,如下圖。
2.進入商戶應用工程的Java Build Path,將libs目錄下的alipaySDK-20150602.jar匯入,如下圖。
3.選中Order and Export,勾選alipaySDK-20150602.jar,如下圖。
將上圖的支付寶sdk更換成微信sdk即可
5.2 如果專案開發使用的Android Studio軟體,匯入步驟如下:
1.將微信SDK拷貝到專案libs資料夾下,如果沒有libs資料夾,就新建一個。
2.如果sdk使用過程中,提示找不到檔案。 進行如下操作,選中sdk檔案,右擊選擇Reveal in Finder
六:修改AndroidManifest.xml配置
1.在商戶應用工程的AndroidManifest.xml檔案裡面新增宣告:
<!--微信-->
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop">
</activity>
複製程式碼
和許可權宣告:
<!--微信-->
<uses-permission android:name="android.permission.INTERNET"/>
複製程式碼
到這裡,微信支付的前期配置已經完成,下面需要完成支付程式碼編寫。
七:支付介面呼叫
- 在點選支付按鈕的點選事件中,我提供的是從後端獲取訂單資訊。
- 需要在新執行緒中呼叫支付介面。程式碼如下:
// 微信按鈕
public void onClick(View view) {
//起一個執行緒
Runnable payRunnable = new Runnable() {
@Override
public void run() {
String data = null;
PayBean payBean = new PayBean();
payBean.setOrderTime("");
String json = new Gson().toJson(payBean);
//json為獲取後端結果時需要提供給後端訂單資訊,例如:時間、金額、訂單屬性等
Log.i("charge request", json);
try {
//data為後端返回資料,其中包括訂單字串
data = postJson(CHARGE_URL, json);
} catch (IOException e) {
e.printStackTrace();
}
// Json解析data
ChargeWXBean charge = new Gson().fromJson(data.replace("package", "packages"), ChargeWXBean.class);
//在mHandler中處理微信調起支付和返回結果回撥
Message msg = new Message();
msg.what = SDK_PAY_WECHAT;
msg.obj = charge;
mHandler.sendMessage(msg);
}
};
// 必須非同步呼叫
Thread payThread = new Thread(payRunnable);
payThread.start();
}
複製程式碼
- 在mHandler中處理調起支付
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == SDK_PAY_WECHAT) {
ChargeWXBean charge = (ChargeWXBean) msg.obj;
String packsges = charge.getResult().getCredential().getPackages();
String appid = charge.getResult().getCredential().getAppid();
String partenerid = charge.getResult().getCredential().getPartnerid();
String prepayid = charge.getResult().getCredential().getPrepayid();
String noncestr = charge.getResult().getCredential().getNoncestr();
String timestamp = charge.getResult().getCredential().getTimestamp();
String sign = charge.getResult().getCredential().getSign();
// 商戶APP工程中引入微信JAR包,呼叫API前,需要先向微信註冊您的APPID,程式碼如下:
final IWXAPI msgApi = WXAPIFactory.createWXAPI(ThirdActivity.this, null);
// 將該app註冊到微信
msgApi.registerApp(appid);
PayReq req = new PayReq();
req.appId = appid;
req.partnerId = partenerid;
req.prepayId = prepayid;
req.nonceStr = noncestr;
req.timeStamp = timestamp;
req.packageValue = packsges;
req.sign = sign;
msgApi.sendReq(req);
}
}
};
複製程式碼
- 支付結果回撥
參照微信SDK Sample,在net.sourceforge.simcpux.wxapi包路徑中實現WXPayEntryActivity類(包名或類名不一致會造成無法回撥),在WXPayEntryActivity類中實現onResp函式,支付完成後,微信APP會返回到商戶APP並回撥onResp函式,開發者需要在該函式中接收通知,判斷返回錯誤碼,如果支付成功則去後臺查詢支付結果再展示使用者實際支付結果。注意一定不能以客戶端返回作為使用者支付的結果,應以伺服器端的接收的支付通知或查詢API返回的結果為準。(net.sourceforge.simcpux為你的專案包名)程式碼示例如下:
@Override
public void onResp(BaseResp resp) {
Log.d(TAG,"onPayFinish,errCode="+resp.errCode);
// 判斷resultStatus 為“0”則代表支付成功,具體狀態碼代表含義可參考介面文件
if (resp.errCode.equals("0")) {
Toast.makeText(ThirdActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
}else if (resp.errCode.equals("-1")){
// -1為支付失敗,包括使用者主動取消支付,或者系統返回的錯誤
Toast.makeText(ThirdActivity.this, "支付失敗", Toast.LENGTH_SHORT).show();
}else if (resp.errCode.equals("-2")){
// -2為取消支付,或者系統返回的錯誤
Toast.makeText(ThirdActivity.this, "取消支付", Toast.LENGTH_SHORT).show();
}else {
// 其他為系統返回的錯誤
Toast.makeText(ThirdActivity.this, "支付錯誤", Toast.LENGTH_SHORT).show();
}
}
複製程式碼
以下三種為常用結果判斷
0為支付成功 -1為支付失敗 -2為取消支付
調起支付頁面截圖
關注 【網羅開發】微信公眾號,網羅天下方法,方便你我開發,更多Android技術乾貨等待領取,所有文件會持續更新,歡迎關注一起成長!
希望可以幫助大家
如果哪裡有什麼不對或者不足的地方,還望讀者多多提意見或建議
如需轉載請聯絡我,經過授權方可轉載,謝謝