支付寶和微信支付,已經成爲了現在購物類APP上最常見的兩種支付方式。這裏就總結一下實際開發中如何快速又高效在Android開發中集成這兩種支付方式。
首先說一下,關於jar包導入和AndroidManifest文件的配置,此處就不再贅述,官方文檔裏寫的非常清楚。Ctrl+c & Ctrl+v 可以快速完成。
實現
總的來說,兩種支付方式的API集成性已經做得很好。但我們可以做得更好的集成,更好的實現代碼複用。
public class PayActivity extends AppCompatActivity implements View.OnClickListener {
RelativeLayout aliPayWay;
RelativeLayout wxPayWay;
/**
* 訂單id(隨機輸入,沒有任何意義)
*/
private String Id = "8430948930";
/**
* 微信支付方式
*/
private final String payTypeWx = "1";
/**
* 支付寶支付方式
*/
private final String payTypeAli = "2";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pay);
ButterKnife.bind(this);
aliPayWay = V.f(this, R.id.aliPayWay);
aliPayWay.setOnClickListener(this);
wxPayWay = V.f(this, R.id.wxPayWay);
wxPayWay.setOnClickListener(this);
}
public void onClick(View view) {
switch (view.getId()) {
case R.id.aliPayWay:
PayHelper.aliPay(PayActivity.this, Id, payTypeAli);
break;
case R.id.wxPayWay:
PayHelper.wxPay(PayActivity.this, Id, payTypeWx);
break;
}
}
}
上面這個Activity的UI 的實現,以及其點擊事件對Android開發者來說,是很容一定的事情。這裏重點說一下這裏做過簡單封裝的PayHelper類。
public class PayHelper {
private static final int SDK_PAY_FLAG = 1;
private static final String WX_APP_ID = "8490434389793483";//隨機輸入,不能作爲正式使用
private static IWXAPI api;
/**
* 支付寶支付
*
* @param id
* @param payType
*/
public static void aliPay(final Activity mActivity, String id, String payType) {
@SuppressLint("HandlerLeak")
final Handler mHandler = new Handler() {
@SuppressWarnings("unused")
public void handleMessage(Message msg) {
switch (msg.what) {
case SDK_PAY_FLAG: {
PayResult payResult = new PayResult((String) msg.obj);
/**
* 同步返回的結果必須放置到服務端進行驗證(驗證的規則請看https://doc.open.alipay.com/doc2/
* detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
* docType=1) 建議商戶依賴異步通知
*/
String resultInfo = payResult.getResult();// 同步返回需要驗證的信息
String resultStatus = payResult.getResultStatus();
Log.e("alipay", "the resultSatus is " + resultStatus);
// 判斷resultStatus 爲“9000”則代表支付成功,具體狀態碼代表含義可參考接口文檔
if (TextUtils.equals(resultStatus, "9000")) {
Toast.makeText(mActivity, "支付成功", Toast.LENGTH_SHORT).show();
} else {
// 判斷resultStatus 爲非"9000"則代表可能支付失敗
// "8000"代表支付結果因爲支付渠道原因或者系統原因還在等待支付結果確認,最終交易是否成功以服務端異步通知爲準(小概率狀態)
if (TextUtils.equals(resultStatus, "8000")) {
Toast.makeText(mActivity, "支付結果確認中", Toast.LENGTH_SHORT).show();
} else {
// 其他值就可以判斷爲支付失敗,包括用戶主動取消支付,或者系統返回的錯誤
Toast.makeText(mActivity, "支付失敗", Toast.LENGTH_SHORT).show();
}
}
break;
}
default:
break;
}
}
;
};
final String payInfo = getPayInfo(id, payType);
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 構造PayTask 對象
PayTask alipay = new PayTask(mActivity);
// 調用支付接口,獲取支付結果
String result = alipay.pay(payInfo, true);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必須異步調用
Thread payThread = new Thread(payRunnable);
payThread.start();
}
public static void wxPay(Activity mActivity, String Id, String payType) {
api = WXAPIFactory.createWXAPI(mActivity, WX_APP_ID);
api.registerApp(WX_APP_ID);
final String payInfo = getPayInfo(Id, payType);
JSONObject json;
try {
json = new JSONObject(payInfo);
if (null != json && !json.has("retcode")) {
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");
req.extData = "app data"; // optional
api.sendReq(req);
} else {
Log.d("PAY_GET", "返回錯誤" + json.getString("retmsg"));
Toast.makeText(mActivity,
"返回錯誤" + json.getString("retmsg"), Toast.LENGTH_SHORT)
.show();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 根據訂單id及支付方式,獲取用於的支付信息
*
* @param id
* @param payType
* @return
*/
private static String getPayInfo(String id, String payType) {
String info="payInfo_from_server";
return info;
}
}
這個類裏裏面定義了兩個靜態方法,分別對應於支付寶支付和微信支付方式。其內部實現,完全來自於官方Demo。實際開發中,我們重點要實現的方法,應該就只有
private static String getPayInfo(String id, String payType)
這個方法了,在這個方法裏,我們一般根據一些簽名、祕鑰、訂單信息等相關內容,生成支付寶和微信各自需要的支付信息。從安全角度出發,這些支付信息的生成都是放在後臺完成,而APP端要做的就是獲取到這些信息,併發起相關的支付SDK。