Android平台招商银行“一网通”支付对接采坑记

版权声明:本文为博主原创文章,欢迎转载,转载请注明出处。 https://blog.csdn.net/jun5753/article/details/86681308

公司最近的App中需要做支付功能,支付中需要支持微信支付、支付宝支付、一网通支付。本文主要记录在对接Android平台中的“一网通”过程中遇到的坑,如果有类似需求的朋友,可供你参考。

一、为什么说招商银行“一网通”支付有点坑?

1.微信、支付宝支付特点:

这两个支付流程相似,如安装了相应 的App,可以直接调用App支付,如未安装,则用H5 来支付。

不管哪一种情况,以上两种都提供了SDK做了很好的封装。特别是在支付后的状态(支付成功支付失败)都都有相应的支付结果回调返回,让开发者对接起来很方便。有支付结果回调,接下来的流程处理就很顺手。

2.“一网通”支付有何不同。

“一网通”没有类似微信、支付宝的SDK,旧有的“一网通”虽然有键盘封装的SDK,但是在新的接口中,已不再需要。也就是说“一网通”没有任何支付相关的SDK,支付中涉及到的业务(webview加载、签名、加密、支付结果回调处理)都需要开发者自行处理。所以坑就坑在这里。

虽然很坑,流程也是可行的。无非,就是麻烦一 点而已~

二、“一网通”开发注意事项

1.H5支付(Webview)

当手机检查到没有安装“一网通”App时,用webview来加载网页支付,需要注意,一般的H5中加载时是get请求,而此处是post请求。

参见:查询协议API

<form action="请求地址" method="post" />
    <input type="hidden" name="jsonRequestData" value='以上json字符串' />
    <input type="hidden" name="charset" value='UTF-8' />
</form>

实例代码参考:

 override fun refreshPage() {
     //payUrl是“一网通”的接口链接
        webView?.postUrl(payUrl, 		EncodeUtils.urlDecode("jsonRequestData=$requestData").toByteArray())
      
    }

webview中可以用腾讯的x5浏览器,处理加载状态,自行添加加载进度条。

2.关于签名的处理

参考“一网通”官方文档处理,流程可以根据和服务器的约定确定。

实例代码参考:

    //一网通支付(H5网页端)
    private fun prePaymentYWtH5(payType: String) {
        showLoadingDialog(R.string.common_loading)
        PayApi.prepayment(orderNo, payType).attachToLifecycle(this)
            .execute(object : CZObjectCallback<PreOrderEntity>(PreOrderEntity::class.java) {
                override fun success(data: PreOrderEntity) {
                    dismissLoadingDialog()
                    val content = data.prepay
                    PayRoute.toPayYwtH5(content).navigation(this, CODE_PAY_H5)
                }

                override fun error(code: Int, message: String) {
                    super.error(code, message)
                    dismissLoadingDialog()
                    shortToast(message)
                }
            })
    }

例如:可以在生成预付款信息的接口返回相应的信息,返回的信息中就处理了平台约定的加密规则这些,客户端直接调用。数据类似这样:

jsonRequestData =
  {
	"reqData": {
		"amount": "0.01",
		"branchNo": "0023",
		"date": "20190115",
		"dateTime": "20190115172341",
		"merchantNo": "0101168",
		"orderNo": "43761407182063502",
		"payNoticeUrl": "http://test.1688hyl.com/v1.0/cmbchina/",
		"returnUrl": "haoyunlai://callback"
	},
	"sign": "e33e11ddba21ef5d43da6f4e8ce896a08b946ccd8a445c5a6f9ff39c8884dbd6d54",
	"signType": "SHA-256",
	"version": "1.0"
}
3.h5中支付回调处理注意

支付结果回调:

   override fun initListener() {
        super.initListener()
        webView?.webViewClient = object : WebViewClient() {
            override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {

                //商户按钮 10s 倒计时或点击“返回商户”监听事件 ,RETURN_URL是和平台约定的接口,具体参考官方文档 
                if (url.equals(RETURN_URL, ignoreCase = true)) {
                    //webView成功时的回调
            PayRoute.toPayResult(PayResultActivity.PAY_RESULT_SUCCESS).navigation(this) 						{
                       // do what you want to do
                        }
                }
                return super.shouldOverrideUrlLoading(view, url)
            }
        }
		
       //webview中返回事处理
        getTitleLayout().setOnBackClickListener {
            setResult(Activity.RESULT_OK)
            finish()
        }
    }

注意:在用户点击“返回商户”或在倒计时10秒结束后表式支付成功,这里可以理解为有支付成功的回调,但是 如果用户点击了返回事件,“一网通”并没有提供该支付状态的回调,点击返回事件可能发生在未支付、支付失败等时机,所以这里我们需要自行处理。我在这里的处理方式是,在用户回到上一界面时,马上检查当前的订单号状态,根据服务器的返回结果来判断用户是否支付成功。

参考实例代码:

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        if (requestCode == CODE_PAY_H5 && resultCode == Activity.RESULT_OK) {
            //一网通h5界面 监听用户返回事件 检查支付状态 跳到相应的状态界面
            checkPayResult(orderNo)
        }
    }
4.本地App 支付回调处理注意

支付时如果检查到已安装招商银行一网通的支付App,则调用本地App支付。

参考实例代码:

	//唤醒一网通客户端
    private fun callCMBApp(preData: String) {
        val url =
            "cmbmobilebank://CMBLS/FunctionJump?action=gofuncid&funcid=200007&serverid=CMBEUserPay&requesttype=post&cmb_app_trans_parms_start=here&charset=utf-8&jsonRequestData=$preData"

        try {
            val intent = Intent()
            val data = Uri.parse(url)
            intent.data = data
            intent.action = "android.intent.action.VIEW"
            startActivity(intent)

        } catch (e: Exception) {
            LogUtil.d(e.printStackTrace())
        }
    }

执行上述代码后,跳到第三方的app去支付。

注意:一网通本地支付结果状态没有类似微信支付的回调,需要自行处理。

参考官方文档:支付成功后或失败后 需要回到当前的App,此时注意设置当前的启动模式为singleTop(栈顶复用,防止出现多个机同的界面)

另外也需要注意设置scheme(第三方支付app唤醒当前App),这里需要格外注意,当时按照文档

Android接入要点说明

在scheme设置上官网是这样告诉我们的

image-20190129143424668

结果试了很久都不能成功,联系”招商银行一网通支付技术支持“后,尝试写demo 模拟来唤醒,最后调整格式才成功。这里可以深入了解一下scheme如何唤醒app。

intent.setData(Uri.parse(“haoyunlai://payCallback”))

如果你按照官方也不能成功,可以参考一下我的实例代码,如下所示:

 <!-- 支付 -->
        <activity
            android:name=".PayActivity"
            android:configChanges="orientation|keyboardHidden|screenSize"
            android:launchMode="singleTop"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />

                <!--第三方app 唤醒app 方法intent.setData(Uri.parse("haoyunlai://payCallback"));-->
                <data
                    android:host="callback"
                    android:scheme="haoyunlai" />
            </intent-filter>
        </activity>

检查支付回调,为了安全性,直接向服务器查询订单状态来判断。

实例代码如下:

 //从后台进入前台时执行的方法: 针对一网通本地支付状态的回调监听
    override fun onRestart() {
        super.onRestart()
 		checkPayResult(orderNo)
    }
	//或者在设置启动模式为singleTop后 建议用以下方法替换。
   override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
		checkPayResult(orderNo)
    }

三、小结

在对接过程中,先仔细阅读一下官方文档,再参考一下网上的教程,看一下有哪些坑已被采过。最后在支付对接的过程如有疑问,最好直接联系 招商银行一网通支付技术支持,有些问题 文档上并没有提到,有些问题需要一网通那边配合解决。以我对接为例,在支付成功后,在支付成功的界面上,开始无论如何都无法点击”返回商家“触发事件,检查了和服务器的各种设置,如检查returnurl设置,都是对的。最后让那边配合检查一下,最后就好了。所以有问题及时和支持人员沟通,虽然和微信支付、支付宝支付比起来有点坑,但终究还是能对接成功的。

以上,是我对接过程中的采坑记录,如有任何疑问或不对的地方或更好的地方 ,欢迎交流~

参考:

1.android招商银行“一网通”开发详解

2.招行一网通集成

3.招商银行官方开发文档

猜你喜欢

转载自blog.csdn.net/jun5753/article/details/86681308