一、前言
現(xiàn)在第三方支付在市場上幾乎變成了不可或缺的支付方式妇萄,其中支付寶微信在其中可謂是翹楚蜕企,寫這篇文章的目的旨在給剛接觸支付或者是在集成的時候遇到坑的同胞們。
二冠句、支付寶的接入
在這里只講app支付轻掩,即在app里面集成支付sdk,在用戶支付的時候喚起支付寶進行支付懦底,下面講一下如何接入支付寶
1.集成sdk,將alipaySdk-20161009(我在項目中使用的就是20161009版本).jar添加到應用libs目錄下唇牧,并添加到庫里面去
2.在manifest中進行注冊相應的activity,其中h5payactivity,是用戶手機中沒有安裝支付寶的時候跳轉的h5頁面,后者是已經(jīng)安裝支付寶的時候跳轉的界面
<!--支付寶頁面-->
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind" />
<activity
android:name="com.alipay.sdk.auth.AuthActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind" />
3.聲明權限丐重,和添加混淆腔召,這些權限無非就是網(wǎng)絡權限,寫入權限嗎弥臼,讀取手機狀態(tài)的權限宴咧,等,這點過径缅,沒有什么坑
<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" />
添加混淆
-libraryjars libs/alipaySdk-20161009.jar
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
4.在代碼里面添加支付
首先是一堆參數(shù)掺栅,在這個里面坑挺多的,其中這些支付請求參數(shù)由于安全性的考慮需要后臺進行返回纳猪,在返回的時候進行加密處理氧卧,然后客戶端接收之后進行解密處理,在項目里面我們用的加密方式是des加密氏堤。參數(shù)詳細
https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.x7kkCI&treeId=204&articleId=105465&docType=1
其中請求參數(shù)appid沙绝,sign是后臺生成的一個簽名,其生成步驟鼠锈,詳細請見
https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105974&docType=1
支付代碼如下:
HttpDataResultMall.userRecharge(Constants.USER_RECHARGE_AL, btnChongZhizhifu.getText().toString().substring(2, btnChongZhizhifu.getText().toString().length() - 1), new DataResult<CommonBean<DataBean>>() {
@Override
public void onSuccessData(CommonBean<DataBean> result) {
if (result.isSuccess()) {
//進行解密
String des = UtilDES.ebotongDecrypto(result.getData().getDes());
LogUtil.i("===============>>" + des);
payV2(view, des);
} else {
dialog.dismiss();
chongzhiPopwindow.dismiss();
showToast(result.getData().getDes());
}
}
});
通過向后臺請求支付參數(shù)闪檬,返回之后通過des解密進行調用支付寶的支付接口
Runnable payRunnable = new Runnable() {
@Override
public void run() {
PayTask alipay = new PayTask(AccountActivity.this);
Map<String, String> result = alipay.payV2(orderInfo, true);
Log.i("msp", result.toString());
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
handler.sendMessage(msg);
}
};
Thread payThread = new Thread(payRunnable);
payThread.start();
5 . 通過handler進行處理返回信息
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
switch (message.what) {
case SDK_PAY_FLAG:
PayResultBean payResultBean = new PayResultBean((Map<String, String>) message.obj);
if (payResultBean.getResultStatus().equals("9000")) {
dialog.dismiss();
chongzhiPopwindow.dismiss();
//更新聯(lián)賽幣
getUserCoin();
} else {
dialog.dismiss();
chongzhiPopwindow.dismiss();
Toast.makeText(AccountActivity.this, payResultBean.getMemo(), Toast.LENGTH_SHORT).show();
}
break;
}
return false;
}
});
在resulestate =9000的時候說明成功支付,其他數(shù)據(jù)說明如下所示:
9000 訂單支付成功
8000 正在處理中购笆,支付結果未知(有可能已經(jīng)支付成功)粗悯,請查詢商戶訂單列表中訂單的支付狀態(tài)
4000 訂單支付失敗
5000 重復請求
6001 用戶中途取消
6002 網(wǎng)絡連接出錯
6004 支付結果未知(有可能已經(jīng)支付成功),請查詢商戶訂單列表中訂單的支付狀態(tài)
其它 其它支付錯誤
到此同欠,支付寶的接入便成功完成样傍,其中在簽名的時候可能坑比較多,如果有什么問題的話铺遂,歡迎加qq群進行討論衫哥, 570650538
三、微信的接入
在支付的時候微信的坑算是比較多的襟锐,其中微信跟支付寶的接入大同小異撤逢,下面我就來帶大家一塊接入一下,
1.集成sdk,將libammsdk.jar添加到libs目錄下面粮坞,在此需要注意的是有的項目可能集成了友盟+的第三方登錄和分享到微信的功能笛质,那么在編譯的時候可能會造成沖突,這個不用擔心捞蚂,把友盟中相應的jar包刪掉就行了
2.和支付寶一樣,微信在支付的時候同樣需要傳一系列的參數(shù)跷究,同樣appid 和sign等一系列重要的參數(shù)姓迅,均由后臺提供,在返回的時候直接解密獲取請求參數(shù),然后調用微信的支付接口進行支付丁存,在Android 端后臺設置的時候需要一個應用簽名肩杈,其生成方法如下所示,這個如果不正確的話解寝,就會造成支付的失敗扩然,詳細請見
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
3.具體代碼如下,調用支付接口
String des = UtilDES.ebotongDecrypto(result.getData().getDes());
Message message = handler.obtainMessage();
message.what = SDK_WXPAY_FLAG;
message.obj = des;
handler.sendMessage(message);
其中des,是生成的后臺發(fā)送過來的支付請求參數(shù)在此進行解密聋伦,通過handler,進行輪循處理返回的消息夫偶,
private Handler handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
switch (message.what) {
case SDK_WXPAY_FLAG:
try {
JSONObject json = new JSONObject((String) message.obj);
api = WXAPIFactory.createWXAPI(AccountActivity.this, Constants.WX_APPID);
api.registerApp(Constants.WX_APPID);
PayReq req = new PayReq();
req.appId = json.getString("appid");
req.partnerId = json.getString("partnerid");
req.prepayId = json.getString("prepayid");
req.nonceStr = json.getString("noncestr");
req.timeStamp = json.getString("timestamp");
req.packageValue = json.getString("package");
req.sign = json.getString("sign");
api.sendReq(req);
dialog.dismiss();
chongzhiPopwindow.dismiss();
} catch (Exception e) {
Log.e("PAY_GET", "異常:" + e.getMessage());
Toast.makeText(AccountActivity.this, "異常:" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
break;
}
return false;
}
});
在支付處理的時候,微信和支付寶有點不一樣就是微信會新建一個頁面觉增,支付之后跳轉到相應的頁面進行處理兵拢,
在mainfest里面進行添加結果處理頁面,其中需要注意的是返回結果的activity名稱不能錯逾礁,這是由微信支付api決定的
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
activity里面相應處理代碼:
@ContentView(R.layout.activity_wxpayentry_)
public class WXPayEntryActivity extends BaseActivity implements IWXAPIEventHandler{
private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
private IWXAPI api;
@ViewInject(R.id.tv_wxpay_result)
private TextView tvPayResult;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setToolbar("支付結果");
api = WXAPIFactory.createWXAPI(this, Constants.WX_APPID);
api.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq baseReq) {
}
@Override
public void onResp(BaseResp baseResp) {
int code= baseResp.errCode;
if (code == 0){
//顯示充值成功的頁面和需要的操作
tvPayResult.setText("充值成功");
}
if (code == -1){
//錯誤
tvPayResult.setText("充值失敗");
}
if (code == -2){
//用戶取消
tvPayResult.setText("用戶取消");
}
}
}
在返回的code值分別為0说铃,-1,-2嘹履,分別代表成功腻扇,失敗,取消砾嫉,在具體項目里面開發(fā)人員可以定義相應的頁面進行處理返回結果