首先奉上调起支付页面截图
一:介绍
项目中要用到支付功能,需要支付宝支付、微信支付、银联支付,所以打算总结一下,方便以后的查阅,也方便大家, 用到的地方避免再次被坑。
今天我们就主要介绍一下支付宝支付,其他支付也给出了对应的连接。
在做支付之前,在网上也查寻了资料,大多都说,支付接入坑太多,微信坑最多,银联文档太复杂。
其实如果接入的多的话,那些套路都可以绕着走。
网上的经验什么的大都是比较老的,比较新的能用到的文章不多(但是好文章还是有的,对我帮助也很大),下面给大家详细介绍一下,帮助大家绕开坑。
二:交互流程
建议先把开发文档仔仔细细看一遍,一定要看,刚开始的时候没有老老实实地看完,结果遇到很多的坑,浪费的挺多的时间的,所以建议一定要好好看看,特别是交互流程这一部分。
2.1 功能流程
1.第4步:调用支付接口:此消息就是本接口所描述的开发包提供的支付对象PayTask,将商户签名后的订单信息传进pay方法唤起支付宝收银台,订单格式具体参见“请求参数说明”。
2.第5步:支付请求:手机支付宝支付开发包将会按照商户客户端提供的请求参数发送支付请求。
3.第8步:接口返回支付结果:商户客户端在第4步中调用的支付接口,会返回最终的支付结果(即同步通知),参见“同步通知参数说明”。
4.第12步:异步发送支付通知:手机支付宝支付服务器端发送异步通知消息给商户服务器端(备注:第12步一定发生在第6步之后,但不一定晚于7~11步),参见“服务器异步通知参数说明”。
2.2 数据交互
支付宝支付的功能流程相比较微信支付来说简单的很,如上面两张图展示的,我们的App(也就是商户客户端)所做的大概只有三个步骤:
生成订单
调用支付宝接口,发送订单
返回订单支付结果并处理
三:下载支付宝SDK
支付宝业务众多,真想找到想要的支付sdk还是要费一番功夫的,这里给出了最新的sdk地址(注意的是下载出来的SDK包里面并没有传说中的开发文档,需要其他地方找或者看网页上的)。
想要接入支付宝移动支付功能,必须在支付宝商家服务平台进行申请与审核。移动支付功能需要企业或者个体工商户进行申请,审核通过之后方可使用。
如何与支付宝签约并审核请参考官方文档:移动支付-接入指南,里面详细介绍了产品签约与审核流程。并且详细介绍了申请成功之后如何查看或生成必要的一些配置参数。
四:导入开发SDK
4.1 如果项目开发使用的Eclipse软件,导入步骤如下:
1.将alipaySDK-20150602.jar包放入商户应用工程的libs目录下,如下图。
2.进入商户应用工程的Java Build Path,将libs目录下的alipaySDK-20150602.jar导入,如下图。
3.选中Order and Export,勾选alipaySDK-20150602.jar,如下图。
4.2 如果项目开发使用的Android Studio软件,导入步骤如下:
1.将支付宝SDK拷贝到项目libs文件夹下,如果没有libs文件夹,就新建一个。
2.如果sdk使用过程中,提示找不到文件。
进行如下操作,选中sdk文件,右击选择Reveal in Finder
五:修改AndroidManifest.xml配置
1.在商户应用工程的AndroidManifest.xml文件里面添加声明:
<activity
android:name="com.alipay.sdk.app.H5PayActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind" >
</activity>
<activity
android:name="com.alipay.sdk.auth.AuthActivity"
android:configChanges="orientation|keyboardHidden|navigation"
android:exported="false"
android:screenOrientation="behind" >
</activity>
和权限声明:
<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" />
六:添加混淆规则
在商户应用工程的proguard-project.txt里添加以下相关规则:
-libraryjars libs/alipaySDK-20150602.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 *;}
第一行中的alipaySDK-20150602.jar,其中20150602是此版本发布的日期,注意将其修改为你导入的Jar的相应的文件名。
到这里,支付宝支付的前期配置已经完成,下面需要完成支付代码编写。
七:支付接口调用
- 在点击支付按钮的点击事件中,我提供的是从后端获取订单字符串,然后调用支付宝接口,调起支付。
- 需要在新线程中调用支付接口。代码如下:
// 支付按钮
public void onClick(View view) {
//起一个线程
Runnable payRunnable = new Runnable() {
@Override
public void run() {
String data = null;
PayBean payBean = new PayBean();
payBean.setOrderTime("");
String json = new Gson().toJson(payBean);
//json为获取后端结果时需要提供给后端订单信息,例如:时间、金额、订单属性等
Log.i("charge request", json);
try {
//data为后端返回数据,其中包括订单字符串
data = postJson(CHARGE_URL, json);
} catch (IOException e) {
e.printStackTrace();
}
// Json解析data
ChargeBean charge = new Gson().fromJson(data, ChargeBean.class);
//获取调起支付所需要的字符串credential
String credential = (String) charge.getResult().getCredential();
// 调起支付界面
PayTask alipay = new PayTask(ThirdActivity.this);
Map<String, String> result = alipay.payV2(credential, true);
//在mHandler中处理支付宝返回结果
Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
};
// 必须异步调用
Thread payThread = new Thread(payRunnable);
payThread.start();
}
- 在mHandler中处理支付结果
private Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == SDK_PAY_FLAG) {
Toast.makeText(ThirdActivity.this, (String) msg.obj,
Toast.LENGTH_LONG).show();
PayResult payResult = new PayResult((Map<String, String>) msg.obj);
/**
对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。
*/
String resultInfo = payResult.getResult();// 同步返回需要验证的信息
String resultStatus = payResult.getResultStatus();
// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
if (resultStatus.equals("9000")) {
Toast.makeText(ThirdActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
}else if (resultStatus.equals("4000")){
// 4000为支付失败,包括用户主动取消支付,或者系统返回的错误
Toast.makeText(ThirdActivity.this, "支付失败", Toast.LENGTH_SHORT).show();
}else if (resultStatus.equals("6001")){
// 6001为取消支付,或者系统返回的错误
Toast.makeText(ThirdActivity.this, "取消支付", Toast.LENGTH_SHORT).show();
}else if (resultStatus.equals("8000")) {
// "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
Toast.makeText(ThirdActivity.this, "支付结果确认中", Toast.LENGTH_SHORT).show();
}else {
// 其他为系统返回的错误
Toast.makeText(ThirdActivity.this, "支付错误", Toast.LENGTH_SHORT).show();
}
}
}
};
以下四种为常用结果判断
9000为支付成功
4000为支付失败
6001为取消支付
8000为支付结果确认中