公司最近的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),这里需要格外注意,当时按照文档
在scheme设置上官网是这样告诉我们的
结果试了很久都不能成功,联系”招商银行一网通支付技术支持“后,尝试写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设置,都是对的。最后让那边配合检查一下,最后就好了。所以有问题及时和支持人员沟通,虽然和微信支付、支付宝支付比起来有点坑,但终究还是能对接成功的。
以上,是我对接过程中的采坑记录,如有任何疑问或不对的地方或更好的地方 ,欢迎交流~
参考: