Android银联手机控件支付使用教程

Android银联手机控件支付使用教程

最近刚接入银联手机支付,也是第一次搞这个,就写一写Demo的使用。这里就不贴全部代码了,具体可以下载Demo查看。这个教程提供一个url获取tn号和测试账号,可以直接完成支付过程!


一、银联手机控件支付流程

Android银联手机控件支付使用教程_第1张图片

简单一点就是:手机生成订单信息,发送到app后台服务器–> 服务器使用银联sdk生成tn号–>app接收到tn号,调起控件进行支付–>支付成功,app后台接收到异步通知结果–>app再去app服务器查询
(注:这个教程提供一个url获取tn号和测试账号,可以直接完成支付过程。)

二、集成SDK(Android Studio)

① 添加资源文件:
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/目录下;
效果如下图:
Android银联手机控件支付使用教程_第2张图片
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')

如图:
Android银联手机控件支付使用教程_第3张图片

② 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.** { *; }

三、获取tn码,调起支付控件

  • 注:这里提供url,可直接获取tn码,可直接使用
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

你可能感兴趣的:(Android基础)