公司项目中需要支付功能,现在支付宝、微信支付很方便,也很多人使用,因此,他们是首选。在此记录一下支付宝集成过程,下期为微信支付,敬请期待
授人以鱼不如授人以渔
首先去支付宝官网下载其最新的Android的SDK集成Dmeo
将支付宝jar包添加项目中
- alipaySdk-20160516.jar
可以看到其主要的调用方法在PayDemoActivity类中,下面为主要支付调用方法:
/**
* 完整的符合支付宝参数规范的订单信息
*/
final String payInfo = orderInfo + "&sign=\"" + sign + "\"&" + getSignType();
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 构造PayTask 对象
PayTask alipay = new PayTask(PayDemoActivity.this);
// 调用支付接口,获取支付结果
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();
注意,我们需要异步发支付请求。可以看到他仅仅需要我们 传递好参数
- 完整的符合支付宝参数规范的订单信息
这一步,我公司由服务器返回已经处理好的秘钥,我直接传递给支付宝即可
partner="2088101568358171"&seller_id="xxx@alipay.com"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"¬ify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&sign="lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJIe2pbjm%2F3kb%2FuGkpG%2BwYQYI51%2BhA3YBbvZHVQBYveBqK%2Bh8mUyb7GM1HxWs9k4%3D"&sign_type="RSA"
请求后,我们讲获得返回值result
resultStatus={9000};memo={};result={partner="2088101568358171"&seller_id="xxx@alipay.com"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"¬ify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&success="true"&sign_type="RSA"&sign="hkFZr+zE9499nuqDNLZEF7W75RFFPsly876QuRSeN8WMaUgcdR00IKy5ZyBJ4eldhoJ/2zghqrD4E2G2mNjs3aE+HCLiBXrPDNdLKCZgSOIqmv46TfPTEqopYfhs+o5fZzXxt34fwdrzN4mX6S13cr3UwmEV4L3Ffir/02RBVtU="}
错误码
- 9000 -> 订单支付成功
- 8000 -> 正在处理中
- 4000 -> 订单支付失败
- 6001 -> 用户中途取消
- 6002 ->网络连接出错
回调处理
@SuppressLint("HandlerLeak")
private 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();
// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
if (TextUtils.equals(resultStatus, "9000")) {
Toast.makeText(PayDemoActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
} else {
// 判断resultStatus 为非"9000"则代表可能支付失败
// "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
if (TextUtils.equals(resultStatus, "8000")) {
Toast.makeText(PayDemoActivity.this, "支付结果确认中", Toast.LENGTH_SHORT).show();
} else {
// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
Toast.makeText(PayDemoActivity.this, "支付失败", Toast.LENGTH_SHORT).show();
}
}
break;
}
default:
break;
}
};
};
至此Android客户端集成支付宝已经完成,是不是So easey!
上面是支付宝Demo的代码,我自己写的时候做了优化,毕竟我们集成的支付插件不仅仅只有支付宝,因此需要写一个统一支付pay,在此基础上做好相应的封装,方便后续的拓展,在此说下我的封装思路。
- 新建一个IPay借口,里面仅仅只有pay方法
- 新建一个Pay实现IPay,重写pay方法,实现支付功能,在Pay里面,统一做网络请求操作,如需要从服务器获取==完整的符合支付宝参数规范的订单信息==,微信一样需要这样,因此可以在此类中统一做请求,获得返回值之后,根据调用支付类型,执行相应pay方法。
- 当然也可以建立一个PayHelper 专门用于实现各个支付类型的pay方法,然后在Pay中调用,减少代码量
- 我们要新建一个IPayResultCallBack接口,定义onSuccess、onFail方法,表示支付成功失败的回调
- 新建一个抽象类PayResultCallBack实现IPayResultCallBack,讲onSuceess、onFail放到支付成功/失败相应中,表明支付成功、失败回调方法,到时调用pay方法是,即要传递实现好的回调类对象
支持基本一个可拓展的支付功能基本搭建完成,剩余的仅仅是需要一个一个集成其他支付功能,走的路子任然如此,一个pay,然后回调方法里面处理支付结果!!!
1、IPay
/**
* 支付接口
* Created by kingpeng on 16/5/19.
*/
public interface IPay {
void pay(int payType,String orderInfo);
}
2、Pay
/**
* 支付工具类
* Created by kingpeng on 16/5/19.
*/
public class Pay implements IPay {
private Activity mContext;
private MyCallback mCallback = new MyCallback();
private int mPayType;
private PayHelper mPayHelper;
private IPayResultCallback mPayResultCallback;
public Pay(Activity context, IPayResultCallback payResultCallback) {
mContext = context;
mPayResultCallback = payResultCallback;
mPayHelper = new PayHelper();
}
@Override
public void pay(int payType, String orderInfo) {
mPayType = payType;
ReqParam param = new ReqParam();
param.setAlertProgressDialog(mContext, true);
param.put("orderInfo", orderInfo);
param.put("payway", payType);
RequestUtil.getInstance().postApi3(R.string.payment_app_require, param, mCallback);
}
/**
* 支付宝支付
*
* @param payInfo
*/
private void aliPay(final String payInfo) {
mPayHelper.aliPay(mContext, payInfo, mPayResultCallback);
}
private class MyCallback extends ReqCallbackIml {
@Override
public void onSuccess(int action, String response) {
switch (action) {
case R.string.payment_app_require:
PayParseBean bean = (PayParseBean) GsonUtil.jsonToBean(response, PayParseBean.class);
if (bean != null && bean.errcode == 0) {
switch (mPayType) {
case 1:
//请求支付宝
aliPay(bean.signStr);
break;
case 2:
//ToDo 请求微信
break;
}
} else {
ToastUtils.showDefaultToastCenter(mContext.getApplicationContext(), "获取订单信息失败");
}
break;
}
}
@Override
public void onFail(int action, Throwable e) {
ToastUtils.showDefaultToastCenter(mContext.getApplicationContext(), "获取订单信息失败");
}
}
3、PayHelper
/**
* 支付帮助类
* Created by kingpeng on 16/5/19.
*/
public class PayHelper {
public PayHelper() {
}
/**
* 支付宝支付
*
* @param activity
* @param payInfo
*/
public void aliPay(Activity activity, String payInfo, IPayResultCallback payResultCallback) {
new AlipayTask(activity, payInfo, payResultCallback).execute();
}
private class AlipayTask extends AsyncTask<String, Integer, String> {
private Activity mContext;
private String mPayInfo;
private IPayResultCallback mPayResultCallback;
public AlipayTask(Activity context, String payInfo, IPayResultCallback payResultCallback) {
super();
mContext = context;
mPayInfo = payInfo;
mPayResultCallback = payResultCallback;
}
@Override
protected String doInBackground(String... params) {
// 构造PayTask 对象
PayTask alipay = new PayTask(mContext);
// 调用支付接口,获取支付结果
String result = alipay.pay(mPayInfo, true);
return result;
}
@Override
protected void onPostExecute(String result) {
mPayResultCallback.payResult(result, Constants.PAY_ALIPAY);
}
}
4、PayResultCallbackImpl
/**
* 支付结果回调
* Created by kingpeng on 16/5/19.
*/
public abstract class PayResultCallbackImpl implements IPayResultCallback {
public void payResult(String result, int payType) {
switch (payType) {
case Constants.PAY_ALIPAY:
aliPayResult(result, payType);
break;
case Constants.PAY_WX:
wxPayResult(result, payType);
break;
}
}
/**
* 支付宝支付结果
*
* @param result
* @param payType
*/
private void aliPayResult(String result, int payType) {
PayResult payResult = new PayResult(result);
/**
* 同步返回的结果必须放置到服务端进行验证(验证的规则请看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();
// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
if (TextUtils.equals(resultStatus, "9000")) {
onPaySuccess(result, payType);
} else {
// 判断resultStatus 为非"9000"则代表可能支付失败
// "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
// 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
onPayFail(result, payType);
}
}
/**
* 支付成功
*
* @param result
* @param payType
*/
public abstract void onPaySuccess(String result, int payType);
/**
* 支付失败
*
* @param result
* @param payType
*/
public abstract void onPayFail(String result, int payType);
}