最近项目用到了支付宝支付,但是百度搜到的都是些如何把支付宝官方的demo进行修改,服务器端的代码依旧存留在我们的项目中,非常影响我们的阅读文档能力,在这里,我把服务器代码全部删除,仅仅保留我们android需要调用的方法。
支付宝android集成地址
我们通过这里进行支付宝的集成,相信看这篇文章的同学已经集成完成了支付宝。
在这里postOrderInfoOnServer()方法就是通过调用服务器获取的经过加签等一系列安全逻辑获取我们需要拿到的数据
private String postOrderInfoOnServer() {
OkHttpClient client = new OkHttpClient();
FormBody.Builder builder = new FormBody.Builder();
FormBody formBody = builder.build();
Request request = new Request.Builder()
.url(ConstantValue.URL + "/order/buildOrderInfo")
.post(formBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String result = response.body().string();
Log.i(TAG, "onResponse: 支付宝订单信息" + result);
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(result);
dataAlipay = jsonObject.getString("data");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
//返回出去的数据,我将其定义为全局的成员变量
return dataAlipay;
}
我将dataAlipay返回出去的数据,我将其定义为全局的成员变量
这样我们就算是拿到了订单数据信息的一串代码
我们需要dataAlipay发给支付宝
下面我们直接进行支付宝的调用。
/**
* 支付宝支付
*/
private void aliPay(int orderId, int orderType) {
//从服务器获取支付宝订单信息
postOrderInfoOnServer();
Log.i(TAG, "aliPay: 支付宝订单信息" + dataAlipay);
Runnable payRunnable = new Runnable() {
@Override
public void run() {
// 构造PayTask 对象
PayTask alipay = new PayTask(PayActivity.this);
// 调用支付接口,获取支付结果
Map<String, String> result = alipay.payV2(dataAlipay, true);
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必须异步调用
Thread payThread = new Thread(payRunnable);
payThread.start();
}
1.在alipay.payV2()方法中,我们将从服务器获取到的dataAlipay传入,将返回的result结果通过Message对象存储。
2.最后我们通过重写handleMessage()方法进行支付成功后的逻辑
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@SuppressWarnings("unused")
public void handleMessage(Message msg) {
switch (msg.what) {
case SDK_PAY_FLAG: {
@SuppressWarnings("unchecked")
PayResult payResult = new PayResult((Map<String, String>) msg.obj);
/**
对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。
*/
String resultInfo = payResult.getResult();// 同步返回需要验证的信息
String resultStatus = payResult.getResultStatus();
Log.i(TAG, "handleMessage: " + resultStatus);
// 判断resultStatus 为9000则代表支付成功
if (TextUtils.equals(resultStatus, "9000")) {
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
Toast.makeText(PayActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
//销毁界面
finish();
} else {
// 该笔订单真实的支付结果,需要依赖服务端的异步通知。
Toast.makeText(PayActivity.this, "支付失败", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
};
到这里我们就算基本完成了支付宝支付了。
支付的异步通知优化
我们来分析一下handleMessage()中的方法
payResult.getResultStatus()方法即能获取到支付宝返回给我们的状态码,成功即9000,错误即6001。下面我将通过两点解决,9000的优化扩展以及如何解决6001错误。
9000成功
其实在我们handleMessage()方法中,只是走到了第8步,如果我们想优化第9步,我们需要在if (TextUtils.equals(resultStatus, "9000")
中调用我们自己服务器,将payResult.getResultStatus()获取到的9000状态码传给服务器,服务器进行同步通知,如果服务器返回给我们的数据为成功,我们在Toast显示成功
这样,9.10,11步即完成,剩下的我们交给后台大神们去解决就可以了
6001错误码
在我自己的项目中,调用出来支付宝可能没有显示付款界面,可能会返回
系统繁忙
交易订单失败
等错误,这说明我们客户端其实已经配置好支付宝了,不要将错误扩大化,去考虑别的东西。
我解决的办法是,重新生成一下RSA2公私钥,开发文档中,支付宝给了我们生成公私钥的工具,我们只要按照步骤走就行,十分简单让后台重新配置一下需要返回给我们的订单信息,这样,错误基本就能解决了。