集成微信支付SDK
在集成第三方的時候,首先是要在自己的項目中集成對應的SDK后才可以開發的。這個毋庸置疑。這里給出微信官方的集成文檔,讀者可自行查看,我在這里只對關鍵地方做出說明。
微信官方集成文檔:
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=6e7c5d2622dcc43878e06cd70caaa27a86d3d1d7&lang=zh_CN
如下圖,微信支付sdk已經可以通過gradle來導入了,所以建議還在堅守eclipse的同學趕緊轉入Android studio。
2.大坑---支付回調頁面
先看官方文檔,仔細理解下圖被框住的文字。第一次做微信支付被這句話坑慘了,搞了兩天都TM找不到我到底錯在哪里了,現在想起來就生氣。所以這句話的正確解讀是:在你的包名下一級目錄里面,新建一個文件夾名字為wxapi。而不是像下圖一樣有兩個并列的net.sourceforge.simcpux。
Paste_Image.png
當時之所以被坑的慘,也跟包結構顯示樣式不同有關系。用Android Studio開發時包結構多半是這樣的:
Paste_Image.png
對比以上兩張圖,相信聰明的你一點會發現問題。
微信支付開發步驟
微信SDK集成之后,準備工作也就做好了,接下來就是要寫代碼了,有木有一點小激動呢。官方文檔:pay.weixin.qq.com/wiki/doc/ap…
1.統一下單(服務端做)
為了更加安全,微信推薦統一下單是交給服務端人員來做的,當然也有一下服務端開發人員覺得麻煩,會推到客戶端來做,這個時候千萬別慫,一定要跟他講。
2.請求我們自己的接口
在我們自己的APP中點擊微信支付按鈕后,我們首先要請求一個我們自己服務端的接口,這時服務端需要走統一下單的邏輯,然后將一些參數返回給我們。這里需要注意,嚴格來說的話,這個接口應該返回如下所有參數:
尤其是這個簽名的過程,微信官方強烈建議放在服務端來做。而事實上,會有一些服務端開發人員為了他們自己方便,返回過來的數據是這樣的:
如果這樣的話,簽名過程就要放在客戶端來做嘍。
3.調起微信APP進行支付
調起微信APP是需要請求參數的,也就是上一步中說到的那些參數,當你把這些參數都湊夠了,那么這一步也就沒什么難度了,就是照著模板寫了:
private IWXAPI iwxapi; //微信支付api
/**
*調起微信支付的方法
**/
private void toWXPay() {
iwxapi = WXAPIFactory.createWXAPI(this, null); //初始化微信api
iwxapi.registerApp(appid); //注冊appid appid可以在開發平臺獲取
Runnable payRunnable = new Runnable() { //這里注意要放在子線程
@Override
public void run() {
PayReq request = new PayReq(); //調起微信APP的對象
//下面是設置必要的參數,也就是前面說的參數,這幾個參數從何而來請看上面說明
request.appId = appid;
request.partnerId = partnerId;
request.prepayId = prepayId;
request.packageValue = "Sign=WXPay";
request.nonceStr = nonceStr;
request.timeStamp = timeStamp;
request.sign = sign;
iwxapi.sendReq(request);//發送調起微信的請求
}
};
Thread payThread = new Thread(payRunnable);
payThread.start();
}
4.處理微信支付的回調
處理微信支付的回調就是在剛剛創建的WXEntryActivity中處理。需要實現IWXAPIEventHandler接口,這個接口會要求你實現onResp方法,我們就在這個方法中處理回調。
@Override
public void onResp(BaseResp resp) {
if(resp.getType()==ConstantsAPI.COMMAND_PAY_BY_WX){
if(resp.errCode==0){
Toast.makeText(this, "支付成功", Toast.LENGTH_LONG).show();
}
else {
Toast.makeText(this, "支付失敗", Toast.LENGTH_LONG).show();
}
finish();
}
}
到此微信支付也就完成了,是不是很簡單呀。
簽名問題
前面提到,有時候簽名會讓客戶端來做,那么我們就來看看簽名怎么來搞搞吧。先看看官方的簽名規則:
仔細閱讀上面的簽名規則,應該不難理解。理解不了也沒關系,下面就是我寫好的代碼:
/**
* 調起微信APP支付,簽名
*/
public static String genPackageSign2(List<NameValuePair> params) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < params.size(); i++) { //將參數拼接成鍵值對樣式的字符串
sb.append(params.get(i).getName());
sb.append('=');
sb.append(params.get(i).getValue());
sb.append('&');
}
sb.append("key=");
sb.append(Constants.API_KEY); //拼接key
//進行MD5加密,并轉為大寫
String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
return packageSign; //返回簽名
}
/**
* MD5加密算法
*/
public final static String getMessageDigest(byte[] buffer) {
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
try {
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(buffer);
byte[] md = mdTemp.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
return null;
}
微信支付的封裝
由于微信支付不涉及很多業務邏輯,因此完全可以封裝成工具類。這里對微信支付做了封裝,并且用了Builder設計模塊(類似Dialog的使用)。封裝后的使用案例:
//在服務端簽名
findViewById(R.id.btn1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//假裝請求了服務器 獲取到了所有的數據
WXPayUtils.WXPayBuilder builder = new WXPayUtils.WXPayBuilder();
builder.setAppId("123")
.setPartnerId("56465")
.setPrepayId("41515")
.setPackageValue("5153")
.setNonceStr("5645")
.setTimeStamp("56512")
.setSign("54615")
.build().toWXPayNotSign(MainActivity.this,"123");
}
});
//在客戶端簽名
findViewById(R.id.btn2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//假裝請求了服務端信息,并獲取了appid、partnerId、prepayId
WXPayUtils.WXPayBuilder builder = new WXPayUtils.WXPayBuilder();
builder.setAppId("123")
.setPartnerId("213")
.setPrepayId("3213")
.setPackageValue("Sign=WXPay")
.build()
.toWXPayAndSign(MainActivity.this,"123","key");
}
});
經過這樣封裝后,下次再接入微信支付就簡單多了。會少走很多彎路。具體封裝請參考github:github.com/chaohengxin…
微信支付到此也就總結完了,是不是感覺很簡單呢,不過一定要注意別掉坑里。
詳細代碼請參考github:github.com/chaohengxin…