好久沒有寫部落格了,因為前段時間公司新上線一個APP實在是太忙了,天天加班。累成狗了!
然鵝,終於順利上線了!這兩天能清閒一下了,學習寫一下這期中遇到的問題吧!!!
支付,在APP中是最常用的問題。同事有很多迷惑,所以寫一篇文章,為正在迷惑的你們。
1.微信支付
首先官方文件實在是沒有看懂,裡面有很多東西都沒有提及到,反正最以前我看的時候就沒有看懂可能是能力有限吧!
先說一下我們這邊的需求吧,我們這邊訂單處理是在伺服器,沒有在app內進行,一些欄位都是從伺服器返回的,這裡只要在請求之後,喚起微信支付就算是完成了,還是很簡單的一個操作,下面我們就一步一步往下說吧!
整合步驟如下:
1.首先就是匯入最新的SDK,這個從微信官方資源下載處就可以下載(這裡就不說了)
2.新增必要的許可權
<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"/>
複製程式碼
3.建立一個wxapi的包並且建立一個WXEntryActivity類
這裡有幾點要注意以下:
1.首先這個包必須在你專案的根目錄下建立的,例如應用程式的包名為net.sourceforge.simcpux,則新新增的應該在net.sourceforge.simcpux.wxapi下面)別問我為什麼,人家微信就是這麼要求的!
2.在AndroidManifest中新增相應的標籤
<activity
android:name=".wxapi.WXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
複製程式碼
4.關於APPID存放問題
關於這個APPID的存放,因為做了分享,所以我就直接存放到本地了的靜態欄位中了,還可以從伺服器返回,但是這裡要注意時機,如果你們新增微信登入的話。一定要在這之前返回!!!
5.建立一個WXPayEntryActivity類
建立的這個類我就直接放在wxapi中了,這個類就是微信支付的回掉類!
關於這個類有幾點說明:
1.這個類是整合Activity的實現IWXAPIEventHandler介面的,別忘了在AndroidManifest註冊,否則不走回撥的!
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop"/>
複製程式碼
2.在**onCreat()**方法中要註冊到微信,這裡要注意這個是你微信成功簽名的那個APPID,關於簽名直接用微信提供的工具就可以了!正規公司這些東西是不會讓你去做的,老大會自己搞定的!!!
private IWXAPI api;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//這裡面的APPID就是存放在本地的微信的ID
api = WXAPIFactory.createWXAPI(this, Constants.ACCOUNT.APP_ID);
api.registerApp(WX_APP_ID);
api.handleIntent(getIntent(), this);
}
複製程式碼
3.在**onResp(BaseResp resp)**方法中處理回撥資料,也就是處理回撥失敗啊,成功啊什麼的!
@Override
public void onResp(BaseResp resp) {
Logger.e("WXPayEntryActivity回撥微信支付的結果errCode = " + resp.errCode);
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
int errCode = resp.errCode;
if (errCode == -1) {/*支付失敗*/
Toast.makeText(this, "支付失敗", Toast.LENGTH_LONG).show();
} else if (errCode == 0) {/*支付成功*/
Toast.makeText(this, "支付成功", Toast.LENGTH_SHORT).show();
EventBusUtils.post(new EventBusWechatGoldBean());
} else if (errCode == -2) {/*取消支付*/
Toast.makeText(this, "取消支付", Toast.LENGTH_LONG).show();
}
finish();
}
}
複製程式碼
6.之後就可以在相應的地方從伺服器獲取相應的引數呼叫微信支付了
呼叫的程式碼如下:
/**
* 喚起微信充值介面
*/
private void payWechat(WechatGoldBean wechatGoldBean) {
PayReq req = new PayReq();
req.appId = wechatGoldBean.getAppid();
req.partnerId = wechatGoldBean.getPartnerid();
req.prepayId = wechatGoldBean.getPrepayid();
req.nonceStr = wechatGoldBean.getNoncestr();
req.timeStamp = wechatGoldBean.getTimestamp();
req.packageValue = "Sign=WXPay";
req.sign = wechatGoldBean.getSign();
IWXAPI api = WXAPIFactory.createWXAPI(mContext, wechatGoldBean.getAppid());
api.sendReq(req);
}
複製程式碼
這裡WechatGoldBean是從伺服器請求來的實體類,這裡面封裝了關於微信支付的所有訂單資訊,所以你不用糾結這個類什麼樣,主要知道這些引數就可以了!這樣做的好處就是生成訂單伺服器做比較安全,第二也省去了我們自己的麻煩。
到了這裡基本上都能喚起微信支付了
常見問題:
- 關於微信的簽名要說明的問題: 首先按照微信的簽名的話,一般步驟都可以往下走,但是有一點需要注意就是簽完名之後,如果你打包成正式版的話也就是releasea簽名的話要用正式的包安裝才能喚起微信,否則會出錯的,如果要是想使用Dug簽名的話,你要把簽名後的keystore替換掉android studio的預設簽名就可以使用了。
- 如果你有隻調起來一次,第二次調不起來的。後臺微信輸出是-1的話,是簽名的問題。重新弄一遍簽名就可以了!!!
關於微信支付能只能想到這麼多了,基本上整合就這麼多問題,有什麼不懂得歡迎在下方留言,看到了我會第一時間回覆!!!
2.支付寶支付
其實支付寶支付的話還是比較簡單的按照Demo整合的話基本上沒有什麼問題就是匯入幾個類就可以了。
還是先說一下我們這邊的需求,還是訂單處理在伺服器這邊,沒有在app內進行,一些欄位都是從伺服器返回的,這裡只要請求之後,喚起支付寶支付就算完成了,比較簡單,下面一步一步往下說吧!
整合步驟如下:
1.首先就是匯入最新的SDK,這個從支付寶官方資源下載處就可以下載(這裡就不說了)
2.新增必要的許可權
<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" />
複製程式碼
3.在AndroidManifest中新增相應的標籤
<!-- 支付寶H5頁面支付用的 -->
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind" >
</activity>
<!-- 支付寶App支付頁面用的 -->
<activity
android:name="com.alipay.sdk.auth.AuthActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind" >
</activity>
複製程式碼
4.支付介面呼叫
這裡說明一下,支付寶呼叫的時候必須在非同步執行緒中呼叫!切記
public void payAlipay(final ALipayGoldBean aLipayGoldBean) {
Runnable payRunnable = new Runnable() {
@Override
public void run() {
PayTask alipay = new PayTask((DiamondActivity) mContext);
Map<String, String> result = alipay.payV2(aLipayGoldBean.getPayInfo(), true);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
Thread payThread = new Thread(payRunnable);
payThread.start();
}
複製程式碼
這裡說明一下:這個ALipayGoldBean是從伺服器請求過來的,裡面就一個payInfo引數,其實就是payV2()所需要的定單的資訊(orderInfo)!
5.支付結果的處理
官方文件上說有兩種處理方式,但是作為APP我只按第一種處理方式進行的,第二種沒有研究!
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case SDK_PAY_FLAG:
@SuppressWarnings("unchecked")
PayResult payResult = new PayResult((Map<String, String>) msg.obj);
String resultStatus = payResult.getResultStatus();
// 判斷resultStatus 為9000則代表支付成功
if (TextUtils.equals(resultStatus, "9000")) {/*支付成功*/ Toast.makeText(mContext, "支付成功", Toast.LENGTH_SHORT).show();
} else {/*支付失敗*/
Toast.makeText(mContext, "支付失敗", Toast.LENGTH_SHORT).show();
}
break;
}
}
};
複製程式碼
這裡有幾點說明的問題: 1.這個PayResult從Demo中直接複製過來就行,要不沒有的; 如果你不想複製,好的在下面:
public class PayResult {
private String resultStatus;
private String result;
private String memo;
public PayResult(Map<String, String> rawResult) {
if (rawResult == null) {
return;
}
for (String key : rawResult.keySet()) {
if (TextUtils.equals(key, "resultStatus")) {
resultStatus = rawResult.get(key);
} else if (TextUtils.equals(key, "result")) {
result = rawResult.get(key);
} else if (TextUtils.equals(key, "memo")) {
memo = rawResult.get(key);
}
}
}
@Override
public String toString() {
return "resultStatus={" + resultStatus + "};memo={" + memo
+ "};result={" + result + "}";
}
/**
* @return the resultStatus
*/
public String getResultStatus() {
return resultStatus;
}
/**
* @return the memo
*/
public String getMemo() {
return memo;
}
/**
* @return the result
*/
public String getResult() {
return result;
}
}
複製程式碼
2.關於Handler記憶體洩漏的問題,自己可以改的,如果改不了百度一下就可以了。
至此支付寶支付就算整合完畢了,是不是很簡單!
現在的APP基本上就只接入微信和支付寶,關於銀聯和其它什麼的,我記得有一個叫ping++什麼的。叫什麼名稱忘了,是一個第三方的。
基本上關於支付我就遇到這麼多的問題,其實介入支付還是很簡單的。別慫,就是一頓複製黏貼複製黏貼。OK解決問題,下班回家!!!