一、移动支付的流程。
1. 收集客户端要支付的商品数据
2. 将商品数据提交后台,后台生成支付信息返回客户端
3. 客户端调起移动支付
二、客户端支付的流程
1. 去官方申请移动支付,并集成官方下载的SDK
2. 支付宝:
2.1 拿到后台生成的支付信息
2.2 用支付信息,去创建支付任务PayTask对象
2.3 调用PayTask对象的pay()方法,调起支付宝支付
3.微信支付:
3.1 拿到后台生成的预支付ID
3.2 用预支付ID、微信商户号、微信API密钥、APPID等等生成支付签名,封装在PayReq对象里面。
3.3 用微信API调起微信支付
三、 开发移动支付的分析
1. 我们只关心用的是什么支付方式
2. 我们只关心支付成功还是失败,失败一般是轻提示,成功页面跳转或者其它业务处理
3. 对于微信支付成功回调,很多人有误解,以为只能回调到SDK默认的页面,其实SDK有提供设置回调的类。
四、 支付宝、微信支付的封装
1. 定义支付方式,采用enum
2. 定义支付的业务类
3. 定义成功的回调,采用接口
五、支付方式代码的实现
/**
* 支付类型
* WXPAY:微信支付
* ALIPAY:支付宝
*/
public enum PayType {
WXPAY, ALIPAY
}
六、 支付业务类代码的实现
/**
* ================================================================
* 描述:支付的业务类
* ================================================================
*/
public class PayPresenter implements IWXAPIEventHandler {
private Activity mActivity;
/**
* 支付成功的回调
*/
private OnPayListener mOnPayListener;
/**
* 微信支付支付请求
*/
private PayReq mPayReq;
/**
* 微信支付API
*/
private IWXAPI mApi;
/**
* 微信支付回调的ClassName,默认是设置了当前调起的Activity
*/
private String mCallbackClassName;
// TODO 1. 第一步,所有要调起微信支付Activity的清单配置,和修改Constants里面的配置信息
// <activity
// android:launchMode="singleTask"
// android:windowSoftInputMode="adjustUnspecified|stateHidden">
// <intent-filter>
// <action android:name="android.intent.action.VIEW" />
// <category android:name="android.intent.category.DEFAULT" />
// // TODO 这里改成自己微信开发平台的
// <data android:scheme="wxdfd123456" />
// </intent-filter>
// </activity>
/**
* 2. 第二步,创建PayPresenter
*/
public PayPresenter(Activity activity) {
this.mActivity = activity;
mApi = WXAPIFactory.createWXAPI(activity, Constants.APP_ID);
mPayReq = new PayReq();
mPayReq.options = new PayReq.Options();
// 支付回调的类
mPayReq.options.callbackClassName = activity.getClass().getName();
}
/**
* 3.第三步,复写Activity的方法,调用这个方法
*/
public void onNewIntent(Intent intent) {
mApi.handleIntent(intent, this);
}
/**
* 支付宝支付
*/
public void alipay(final String paymentInfo) {
// TODO paymentInfo是后台Base64加密的支付信息
// TODO 如果后台没Base64 就不用Base64解码
final String payInfo = new String(Base64.decode(paymentInfo));
Observable.just(payInfo)
.map(new Function<String, String>() {
@Override
public String apply(String payInfo) throws Exception {
// 支付宝 构造PayTask 对象
PayTask payTask = new PayTask(mActivity);
// 调用支付接口,获取支付结果的状态
String resultStatus = payTask.pay(payInfo, true);
return resultStatus;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new PayObserver<String>() {
@Override
public void onNext(String resultStatus) {
PayResult payResult = new PayResult(resultStatus);
// 支付宝返回此次支付结果及加签,建议对支付宝签名信息拿签约时支付宝提供的公钥做验签
String result = payResult.getResultStatus();
// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
if (TextUtils.equals(result, "9000")) {// 支付成功
if (mOnPayListener != null) {
mOnPayListener.onCompleted(PayType.ALIPAY);
}
} else {
Toast.makeText(mActivity, "支付失败", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
Toast.makeText(mActivity, "支付失败", Toast.LENGTH_SHORT).show();
}
});
}
/**
* 微信支付
*/
public void wxPay(String paymentInfo) {
// 这是微信支付的预支付ID
// TODO 如果后台没Base64 就不用Base64解码
String payInfo = new String(Base64.decode(paymentInfo));
// 设置回调的Activity
if (!TextUtils.isEmpty(mCallbackClassName)) {
if (mPayReq.options != null) {
mPayReq.options.callbackClassName = mCallbackClassName;
}
}
if (!TextUtils.isEmpty(payInfo)) {
// 发送支付请求
sendPayReq(payInfo);
}
}
/**
* 发送微信支付请求
*/
private void sendPayReq(String payInfo) {
// 生成支付签名 payInfo是预支付ID
WXSignUtil.genPayReq(mPayReq, payInfo);
// 发送支付请求
mApi.sendReq(mPayReq);
}
// 微信回调
@Override
public void onReq(BaseReq baseReq) {
}
// 微信支付结果回调
@Override
public void onResp(BaseResp resp) {
String text = "支付提示";
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
text = "支付成功";
if (mOnPayListener != null) {
mOnPayListener.onCompleted(PayType.WXPAY);
}
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
text = "支付失败";
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
text = "认证拒绝";
break;
default:
text = "未知错误";
break;
}
Toast.makeText(mActivity, text, Toast.LENGTH_SHORT).show();
}
/**
* 支付成功回调
*/
public interface OnPayListener {
void onCompleted(PayType payType);
}
/**
* 设置支付成功回调
*/
public void setOnPayListener(OnPayListener onPayListener) {
this.mOnPayListener = onPayListener;
}
/**
* 设置微信支付回调到哪个Activity
*/
public void setCallbackClassName(Activity activity) {
if (activity == null) {
return;
}
this.mCallbackClassName = activity.getClass().getName();
}
}
七、WXSignUtil微信签名抽取的一个工具类
/**
* 微信生成签名的工具类
*/
public class WXSignUtil {
/**
* 微信----生成支付签名
*/
public static void genPayReq(PayReq payReq, String prepayId) {
payReq.appId = Constants.APP_ID;
payReq.partnerId = Constants.MCH_ID;
payReq.prepayId = prepayId;
payReq.packageValue = "Sign=WXPay";
payReq.nonceStr = genNonceStr();
payReq.timeStamp = String.valueOf(genTimeStamp());
Map<String, String> maps = new LinkedHashTreeMap<>();
maps.put("appid", payReq.appId);
maps.put("noncestr", payReq.nonceStr);
maps.put("package", payReq.packageValue);
maps.put("partnerid", payReq.partnerId);
maps.put("appid", payReq.appId);
maps.put("prepayid", payReq.prepayId);
maps.put("timestamp", payReq.timeStamp);
payReq.sign = genAppSign(maps);
}
private static String genNonceStr() {
Random random = new Random();
return MD5.getMessageDigest(String.valueOf(random.nextInt(10000))
.getBytes());
}
/**
* 时间戳
*/
private static long genTimeStamp() {
return System.currentTimeMillis() / 1000;
}
private static String genAppSign(Map<String, String> maps) {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> me : maps.entrySet()) {
sb.append(me.getKey());
sb.append('=');
sb.append(me.getValue());
sb.append('&');
}
sb.append("key=");
sb.append(Constants.API_KEY);
String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
return appSign;
}
}
八、Activity调用支付
1. 清单配置
<activity
android:name=".ui.PayTestActivity"
android:exported="true"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustUnspecified|stateHidden">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
// TODO 这里改成自己微信开发平台的
<data android:scheme="wxdfd123456" />
</intent-filter>
</activity>
2. 创建支付业务类PayPresenter
3. 复写Activity的onNewIntent(Intent intent)方法
/**
* 复写Activity方法
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
if (mPayPresenter != null) {
mPayPresenter.onNewIntent(intent);
}
}
4. 设置PayPresenter回调监听
mPayPresenter.setOnPayListener(new PayPresenter.OnPayListener() {
@Override
public void onCompleted(PayType payType) {
// TODO 支付成功的回调
}
});
5. 发起支付
// 这是发起支付宝支付
mPayPresenter.alipay(payInfo);
// 这是发起微信支付
mPayPresenter.wxPay(payInfo);
至此整个支付已搞定,而且微信支付的回调也在当前调用的Activity,是不是爽YY。
网友评论