一:介绍
项目中要用到支付功能,需要支付宝支付、微信支付、银联支付,所以打算总结一下,方便以后的查阅,也方便大家, 用到的地方避免再次被坑。
今天我们就主要介绍一下银联控件支付,其他支付也写了对应教程,并且给出了连接。
集成前首先要看看文档,银联手机控件支付,里面包含需要的库文件和详细的文档。鉴于小伙伴们不容易找到,好事做到底,送上截图方便下载。
二:支付流程介绍
通过支付控件进行交易的流程如下图:
流程图说明:
(1)用户在客户端中点击购买商品,客户端发起订单生成请求到商户后台;
(2)商户后台收到订单生成请求后,按照《手机控件支付产品接口规范》组织并推送订单信息至银联后台;
(3)银联后台接收订单信息并检查通过后,生成对应交易流水号(即TN),并回复至商户后台(应答要素:交易流水号等);
(4)商户后台接收到交易流水号(TN),将交易流水号返回至客户端;
(5)客户端通过交易流水号(TN)调用支付控件;
(6)用户在支付控件中输入相关支付信息后,由支付控件向银联后台发起支付请求;
(7)支付成功后,银联后台将支付结果通知给商户后台;
(8)银联后台同时也将支付结果通知支付控件;
(9)支付控件显示支付结果并将支付结果返回至客户端;
此处备注:我们是通过后台获取订单,我们可以根据商品id等信息通过后台接口获取订单信息,对订单支付流程的签名加密过程后台完成。
三:下载银联SDK
下载之后,找到两个jar包,将UPPayAssistEx.jar和UPPayPluginExPro.jar添加到商户应用的工程中
四:导入开发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,如下图。
将上图的支付宝sdk更换成银联控件支付的两个jar包即可
4.2 如果项目开发使用的Android Studio软件,导入步骤如下:
1.将银联SDK拷贝到项目libs文件夹下,如果没有libs文件夹,就新建一个。
2.如果sdk使用过程中,提示找不到文件。
进行如下操作,选中sdk文件,右击选择Reveal in Finder
除了导入jar包之外,还要导入资源包和依赖包,如下图:
五:修改AndroidManifest.xml配置
1.在商户应用工程的AndroidManifest.xml文件里面添加声明:
<uses-library
android:name="org.simalliance.openmobileapi"
android:required="false" />
<activity
android:name="com.unionpay.uppay.PayActivity"
android:configChanges="orientation|keyboardHidden"
android:excludeFromRecents="true"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" />
<activity
android:name="com.unionpay.UPPayWapActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize" />
和权限声明:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="org.simalliance.openmobileapi.SMARTCARD" />
到这里,银联支付的前期配置已经完成,下面需要完成支付代码编写。
六:支付接口调用
- 在点击支付按钮的点击事件中,我提供的是从后端获取订单信息。
- 需要在新线程中调用支付接口。代码如下:
// 支付按钮
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);
String tn = (String)charge.getResult().getCredential();
//在mHandler中处理微信调起支付和返回结果回调
Message msg = new Message();
msg.what = SDK_PAY_UPPAY;
msg.obj = charge;
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_UPPAY){
String tn = (String) msg.obj;
Log.i("charge", tn);
int ret = UPPayAssistEx.startPay (ThirdActivity.this, null, null, tn, "01");
}
}
};
- 支付结果回调
支付完成后,获取支付控件支付结果,并添加相应处理逻辑,只需实现调用Activity中的onActivityResult()方法即可,支付成功时会返回商户客户端支付结果和签名信息。
控件返回的结果信息仅作为参考,商户订单是否成功支付应该以商户后台主动到全渠道查询的结果或者收到全渠道支付结果通知为准。
示例代码如下:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
/*************************************************
* 步骤3:处理银联手机支付控件返回的支付结果
************************************************/
if (data == null) {
return;
}
String msg = "";
/*
* 支付控件返回字符串:success、fail、cancel 分别代表支付成功,支付失败,支付取消
*/
String str = data.getExtras().getString("pay_result");
if (str.equalsIgnoreCase("success")) {
// 支付成功后,extra中如果存在result_data,取出校验
// result_data结构见c)result_data参数说明
if (data.hasExtra("result_data")) {
msg = "支付成功!";
} else if (str.equalsIgnoreCase("fail")) {
msg = "支付失败!";
} else if (str.equalsIgnoreCase("cancel")) {
msg = "用户取消了支付";
}
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("支付结果通知");
builder.setMessage(msg);
builder.setInverseBackgroundForced(true);
builder.setNegativeButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
}
以下三种为常用结果判断
success为支付成功
fail为支付失败
cancel为取消支付