手机网站支付转Native支付--Android
来源:互联网 发布:java中dao是什么意思 编辑:程序博客网 时间:2024/04/29 05:45
背景
为了节约开发成本,很多Native-H5混合App采用手机网站支付的方式去实现支付模块。但手机网站支付的网络依赖比较严重,也通常需要经过更多的验证,这种种原因导致手机网站支付的成功率比Native支付低,对商户的利益造成影响。
简介
手机网站支付转Native支付是支付宝标准版SDK内置的一项功能,能够帮助Native-H5混合App以极低的接入成本极大地提升支付成功率。
手机网站支付PK手机网站转Native支付
主要区别是:如果用户手机安装了支付宝App,手机网站转Native支付方式会跳转到支付宝App中进行订单支付,用户体验和支付成功率均优于手机网站支付方式。除此之外,还能使用手机网站支付没有提供的功能,例如:指纹支付、手环、手表支付、免密支付等。
如果用户手机没有安装支付宝App怎么办? 如果用户手机没有安装支付宝App,将在SDK提供的WebView中打开H5页面进行支付。即便如此,由于SDK与服务端的交互携带账号信息,仍比不携带任何账号信息的普通手机网站支付体验更好。
如何实现手机网站转Native支付
要实现上述功能需接入我们提供的SDK。
下载Demo
接入过程十分简单,可以以Demo为参考,该Demo程序只有一个功能:创建一个WebView,在WebView中拦截每个URL,然后调用SDK提供的接口检查该URL是否是有效的支付宝订单支付URL,如果是则将该URL传给SDK提供的支付接口进行支付。
Android接入说明
配置
步骤1:导入开发资源
将alipaySdk-20170309.jar包放入商户应用工程module的libs目录下,如下图。
在module的build.gradle中添加依赖
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) ......}
步骤2:修改Manifest
在商户应用工程的AndroidManifest.xml文件里面添加Activity声明:
<!-- 支付宝SDK --><activity android:name="com.alipay.sdk.app.H5PayActivity" android:configChanges="orientation|keyboardHidden|navigation" android:exported="false" android:screenOrientation="behind" ></activity><activity android:name="com.alipay.sdk.auth.AuthActivity" android:configChanges="orientation|keyboardHidden|navigation" android:exported="false" android:screenOrientation="behind" ></activity>
和权限声明:
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.READ_PHONE_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
步骤3:添加混淆规则
在商户应用工程的proguard-rules.pro里添加以下相关规则:
# 支付宝SDK-libraryjars ../appcommon/libs/alipaySdk-20170309.jar-keep class com.alipay.android.app.IAlixPay{*;}-keep class com.alipay.android.app.IAlixPay$Stub{*;}-keep class com.alipay.android.app.IRemoteServiceCallback{*;}-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}-keep class com.alipay.sdk.app.PayTask{ public *;}-keep class com.alipay.sdk.app.AuthTask{ public *;}-dontwarn android.net.SSLCertificateSocketFactory
至此,开发包开发资源导入完成。
接口调用说明
SDK中提供了若干接口,手机网站转Native支付只用到其中一部分,本文未提到的接口无需关注。
如何实现手机网站转Native支付?
步骤一: 在接入方App中拦截H5的URL;
步骤二: 调用SDK提供的“获取订单信息接口(fetchOrderInfoFromH5PayUrl)”对拦截的URL进行处理:
如果返回空字符串则不作任何处理
反之则调用“支付接口(h5Pay)”进行订单支付,并拦截URL
获取订单信息接口
接口原型
/** * 获取H5native支付的信息 * @param h5PayUrl * @return */public synchronized String fetchOrderInfoFromH5PayUrl(String h5PayUrl)
接口功能
从拦截的URL中获取支付请求相关信息,封装成新的订单信息字符串作为返回值。如果该URL不是有效的支付宝支付URL,则返回空字符串。
参数说明
返回值说明
2.如果是无效的支付宝支付URL,则返回空字符串
接口使用方式
调用本接口对拦截的URL进行处理,如果返回值为空字符串则不拦截该URL;如果返回值为非空字符串,则调用SDK提供的支付接口进行支付,使用示例如下:
@Overridepublic boolean shouldOverrideUrlLoading(final WebView view, String url) { final PayTask task = new PayTask(H5PayDemoActivity.this); //处理订单信息 final String ex = task.fetchOrderInfoFromH5PayUrl(url); if (!TextUtils.isEmpty(ex)) { //调用支付接口进行支付 } else { view.loadUrl(url); } return true; }}
支付接口
接口原型
/** * 手机网站支付 * @param h5PayInfo 订单信息 * @param isShowPayLoading 是否显示loading图标 * @return */public synchronized H5PayResultModel h5Pay(String h5PayInfo, boolean isShowPayLoading)
接口功能
完成订单支付并返回支付结果。
参数说明
返回值说明
返回值类型为H5PayResultModel类,包含下述2个成员变量:
9000——订单支付成功
8000——正在处理中
4000——订单支付失败
5000——重复请求
6001——用户中途取消
6002——网络连接出错 returnUrl String 支付结束后应当跳转的url地址
接口使用方式
调用本接口进行支付。如果返回的resultCode为9000,接入方可以提示用户支付成功;返回结果不是9000的情况,无需做任何处理。如果returnUrl不为空,建议接入方跳转到该returnUrl。
- 自定义实现帮助WebView处理各种通知、请求时间的WebViewClient
setWebViewClient(new XxWebViewClient());setWebChromeClient(new XxWebChromeClient());
/** * 处理页面加载的相关事件 */ private class XxWebViewClient extends WebViewClient { private AsyncTask<Void, Void, H5PayResultModel> mPayTask = null; @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); if (mRequestHandler != null) { String title = view.getTitle(); if (!TextUtils.isEmpty(title) && !title.contains("http")) { mRequestHandler.onRequestChangeTitle(view.getTitle()); } } } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (URLUtil.isNetworkUrl(url)) { // 尝试处理支付宝链接 if (url.contains("alipay.com")) { return handleAliPayUrl(url); } return false; } Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); getContext().startActivity(intent); return true; } /** * 处理支付宝支付请求,转 native 支付 */ private boolean handleAliPayUrl(String url) { Context context = getContext(); if (!(context instanceof Activity)) { return false; } final PayTask task = new PayTask((Activity) context); final String ex = task.fetchOrderInfoFromH5PayUrl(url); if (TextUtils.isEmpty(ex)) { return false; } // 启动 native 支付 if (mPayTask == null || mPayTask.getStatus() != AsyncTask.Status.RUNNING) { mPayTask = new AsyncTask<Void, Void, H5PayResultModel>() { @Override protected H5PayResultModel doInBackground(Void... params) { return task.h5Pay(ex, true); } @Override protected void onPostExecute(H5PayResultModel result) { super.onPostExecute(result); String returnUrl = result.getReturnUrl(); if (TextUtils.isEmpty(returnUrl)) { /* * 返回码,标识支付状态,含义如下: * 9000——订单支付成功 * 8000——正在处理中 * 4000——订单支付失败 * 5000——重复请求 * 6001——用户中途取消 * 6002——网络连接出错 */ final String code = result.getResultCode(); if ("9000".equals(code)) { if (mRequestHandler != null) { mRequestHandler.onPaySuccess(); } } } else { // 支付结束后应当跳转的url地址 // 特殊处理地址中的 notify_id Uri uri = Uri.parse(returnUrl); String notifyId = Uri.encode(uri.getQueryParameter("notify_id")); returnUrl = returnUrl.replace(notifyId, Uri.encode(notifyId)); loadUrl(returnUrl); } } }; mPayTask.execute(); } return true; } }
- 客户端处理支付成功后的页面跳转,需要注入JS回调
WebSettings settings = getSettings();settings.setJavaScriptEnabled(true);addJavascriptInterface(new AndroidFinance(), "AndroidFinance");
/** * 实现一些JS回调的方法 */ private class AndroidFinance { // JS回调的版本,这个值需要根据AndroidFinance所支持的方法来调整 private static final String VERSION_ANDROID_FINANCE = "2"; // 常用的提示文案 private static final String MSG_REQUEST_HANDLER_IS_NULL = "处理异常,请重新打开页面"; /** * 支付成功后,客户端跳转 */ @JavascriptInterface public void afterPaySuccess(String jsonParam, String callback, String extra) { if (mRequestHandler != null) { mRequestHandler.onPaySuccess(); } } }
- 处理JS交互请求
/** * 处理WebView内js发起的交互请求 */public interface OnJsRequestHandler { /** * 请求处理支付成功后页面跳转 */ void onPaySuccess();}
- 加载WebView的Activity实现OnJsRequestHandler
@Override public void onPaySuccess() { //处理业务逻辑及页面重定向 }
- 手机网站支付转Native支付--Android
- iOS 手机网站支付转Native支付(使用WKUIDelegate协议获取url)
- 支付宝手机网站支付
- 支付宝手机网站支付
- java支付宝支付,支付手机支付,pc网站支付
- java支付宝支付,支付手机支付,pc网站支付
- 支付宝支付--手机支付(转)
- 支付宝手机网站支付教程
- java接入支付宝手机网站支付
- Payment:支付宝手机网站支付教程
- Java版支付宝手机网站支付
- 支付--支付宝手机网站支付(WAP)
- 手机网站支付宝配置
- 新版支付宝手机网站支付、支付宝pc支付、支付宝无密退款实现
- 支付宝支付--手机支付
- (Android集成支付宝支付)react-native实现支付宝支付
- Magento支付宝手机网站支付插件V3.0版
- 支付宝手机网站支付私钥公钥生成(window环境)
- 关于try finally解惑
- 【MySql】The slave I/O thread stops because master and slave have equal MySQL server UUIDs;
- 51单片机演奏天空之城 c语言源程序
- 欢迎使用CSDN-markdown编辑器
- 水仙花数
- 手机网站支付转Native支付--Android
- "尚学堂杯"哈尔滨理工大学第七届程序设计竞赛 B.Blind Father(贪心)
- 解读Qt OpenGL示例程序 openglwindow
- 【MySql】主从配置
- apache在没有index.html时显示目录文件列表
- Kali Linux 2.0 2016.2 安装VMware tools方法
- error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”
- msvc/gcc 忽略警告(qt)
- 面向对象实例化过程内存分析