最近刚接入银联手机支付,也是第一次搞这个,就写一写Demo的使用。这里就不贴全部代码了,具体可以下载Demo查看。这个教程提供一个url获取tn号和测试账号,可以直接完成支付过程!
简单一点就是:手机生成订单信息,发送到app后台服务器–> 服务器使用银联sdk生成tn号–>app接收到tn号,调起控件进行支付–>支付成功,app后台接收到异步通知结果–>app再去app服务器查询
(注:这个教程提供一个url获取tn号和测试账号,可以直接完成支付过程。)
① 添加资源文件:
1.拷贝upmp_android/sdkPro/jar/data.bin到工程的assets/目录下;
2.拷贝upmp_android/sdkPro/jar/xxx/libentryexpro.so、upmp_android/sdkPro/jar/xxx/libuptsmaddon.so和upmp_android/sdkPro/jar/xxx/libuptsmaddonmi.so到工程的libs/xxx/目录下,其中xxx为 armeabi-v7a、armeabi、arm64-v8a、x86、x86_64之一。
arm64-v8a(x86_64)是针对arm64(x86 64)架构优化的库文件,引入工程后在arm64(x86 64)机型上性能会提升,但是最终生成的程序包将变大。注意: 如果工程中使用了其他的.so库,那么需要所有.so库都有arm64-v8a(x86_64)的版本。
3.拷贝upmp_android/sdkPro/UPPayAssistEx.jar到工程的libs/目录下;
4.拷贝upmp_android/sdkPro/jar/UPPayPluginExPro.jar到工程的libs/目录下;
效果如下图:
arm64-v8a (x86_64)是针对arm64(x86 64)架构优化的库文件,引入工程后在arm64(x86 64)机型上性能会提升,但是最终生成的程序包将变大。注意: 如果工程中使用了其他的.so库,那么需要所有.so库都有arm64-v8a(x86_64)的版本。
在build.gradle添加:
android:
java.srcDirs = ['src/main/java']
assets.srcDirs = ['src/main/assets']
jniLibs.srcDirs = ['libs']
dependencies:
implementation files('libs/UPPayAssistEx.jar')
implementation files('libs/UPPayPluginExPro.jar')
② AndroidManifest.xml文件中注册支付插件使用的Activity
<application>
<uses-library android:name="org.simalliance.openmobileapi" android:required="false"/>
<activity
android:name="com.unionpay.uppay.PayActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:configChanges="orientation|keyboardHidden"
android:excludeFromRecents="true"
android:windowSoftInputMode="adjustResize"/>
<activity
android:name="com.unionpay.UPPayWapActivity"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize"/>
application>
//同时添加,银联支付插件相关权限:
<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-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permissionandroid:name="android.permission.READ_PHONE_STATE"/>
<uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce"/>
<uses-permissionandroid:name="org.simalliance.openmobileapi.SMARTCARD" />
③ 混淆
-dontwarn com.unionpay.**
-keep class com.unionpay.** { *; }
private static final String TN_URL_01 = "http://101.231.204.84:8091/sim/getacptn";
--------------------------------------------------------------------
//访问url 获取tn
@Override
public void run() {
String tn = null;
InputStream is;
try {
String url = TN_URL_01;
URL myURL = new URL(url);
URLConnection ucon = myURL.openConnection();
ucon.setConnectTimeout(120000);
is = ucon.getInputStream();
int i = -1;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((i = is.read()) != -1) {
baos.write(i);
}
tn = baos.toString();
is.close();
baos.close();
} catch (Exception e) {
e.printStackTrace();
}
Message msg = mHandler.obtainMessage();
msg.obj = tn;
mHandler.sendMessage(msg);
}
--------------------------------------------------------------------
//获取tn
@Override
public boolean handleMessage(Message msg) {
Log.e(LOG_TAG, " " + "" + msg.obj);
if (mLoadingDialog.isShowing()) {
mLoadingDialog.dismiss();
}
String tn = "";
if (msg.obj == null || ((String) msg.obj).length() == 0) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("错误提示");
builder.setMessage("网络连接失败,请重试!");
builder.setNegativeButton("确定",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
} else {
tn = (String) msg.obj;
/*************************************************
* 步骤2:通过银联工具类启动支付插件
************************************************/
doStartUnionPayPlugin(this, tn, mMode);
}
return false;
}
调起支付控件:
// “00” – 银联正式环境
// “01” – 银联测试环境,该环境中不发生真实交易
String serverMode = "01";
UPPayAssistEx.startPay (activity, null, null, tn, serverMode);
UPPayAssistEx.jar中定义了启动支付控件的接口,接口定义如下:
public static int startPay(Activity activity, String spId, String sysProvider, String orderInfo, String mode)
参数说明:
activity —— 用于启动支付控件的活动对象
spId —— 保留使用,这里输入null
sysProvider —— 保留使用,这里输入null
orderInfo —— 订单信息为交易流水号,即TN,为商户后台从银联后台获取。
mode —— 银联后台环境标识,“00”将在银联正式环境发起交易,“01”将在银联测试环境发起交易
返回值:
UPPayAssistEx.PLUGIN_VALID —— 该终端已经安装控件,并启动控件
UPPayAssistEx.PLUGIN_NOT_FOUND — 手机终端尚未安装支付控件,需要先安装支付控件
支付完成后,获取支付控件支付结果,并添加相应处理逻辑,只需实现调用Activity中的onActivityResult()方法即可,支付成功时会返回商户客户端支付结果和签名信息。
这里返回的同步支付结果,正式使用时需要去后台app服务器查询支付结果,服务器在支付结束,会接收到异步支付结果,app只需要进行查询即可。
protected void onActivityResult( int requestCode,int resultCode, Intent data)
{
if( data == null ){
return;
}
String msg = "";
String str = data.getExtras().getString("pay_result");
if( str.equalsIgnoreCase(R_SUCCESS) ){
// 如果想对结果数据验签,可使用下面这段代码,
// 但建议不验签,直接去商户后台查询交易结果
// result_data结构见c)result_data参数说明
if(data.hasExtra("result_data")) {
String sign = data.getExtras().getString("result_data");
// 此处的verify建议送去商户后台做验签
// 如要放在手机端验,则代码必须支持更新证书
if(verify(sign)) {
//验签成功,显示支付结果
showResultDialog(" 支付成功! ");
} else {
// 验签失败
}
}
// 结果result_data为成功时,去商户后台查询一下再展示成功
}else if( str.equalsIgnoreCase(R_FAIL) ){
showResultDialog(" 支付失败! ");
}else if( str.equalsIgnoreCase(R_CANCEL) ){
showResultDialog(" 你已取消了本次订单的支付! ");
}
}
返回信息说明:
result_data参数说明:
参数说明:
sign —— 签名后做Base64的数据
data —— 用于签名的原始数据
data中原始数据结构:
pay_result —— 支付结果success,fail,cancel
tn —— 订单号
result_data示例如下:
{"sign":"Xo/pgkzSJSlRTX2e+CjW/k1IjIV1newqfb7p1sDIpK/yPQv9p1jQAdAdKwhBwtyjO3tkFC6I2aLcTaxLHlYQx6/xw9QE0eumkVqAhypk/VyoDWZXxWske+EcduwEkBTxyIgA0ZsbKlpS1JxsciOc6bT+f36jTLa05ZAKZTVErg9sAG3wMjae1TyKd2511Rvvi+tuihYgOmwuMnKzrqksEyqc69wloqi34qx0YqFolMeqQ1UfoglUhZy6s2s4ChKcxHjAFjp/rU/7iHudjAIGtO7+ySahArmw6ltuIxFWYE5xI3Ceur1d11NBphK62it7kBZ1laxUFI98DzalVFQ==", "data" : "pay_result=success&tn=899394085660622736701&cert_id=68759585097"}
这里提供2个测试银行卡号,随便支付!
测试卡号信息:
借记卡:6226090000000048
手机号:18100000000
密码:111101
短信验证码:123456
(短信验证码记得点下获取验证码之后再输入)
贷记卡:6226388000000095;
手机号:18100000000;
cvn2:248;
有效期:1219;
短信验证码:123456
(短信验证码记得点下获取验证码之后再输入)
Demo运行动图:
Demo下载,包含SDK、Android端demo,后台Demo及部分文档
http://download.csdn.net/download/z740852294/10176500