Alipay, China's leading third-party online payment solutionAlipay, China's leading third-party online payment solution

跳转链接集成最佳实践

调用 支付 接口后,针对不同支付方式,支付 接口的响应中会返回不同类型的跳转 URL 用于支付流程的推进。本文为您提供不同端类型对应的跳转 URL 使用最佳实践。关于各个支付方式的 URL 实际返回情况,请参考 部分支付方式的URL返回类型汇总

跳转 URL 参数

针对不同的商户应用端类型(Web, WAP, App),不同支付方式在 支付 接口的响应中会返回以下三种跳转 URL 中的部分或全部,用于支付推进:

链接类型

描述

normalUrl

HTTPS 地址的 URL,用于同一个浏览器页面跳转至支付方式页面。

示例:https://msp.boost-my.com/onlinepayment/authorise?source=alipay-connect&codeValue=https%3A%2F%2Fglobal.alipay.com%2F2810020400931LFH2t2mq1jjJ8zSetyv31VU

applinkUrl

用于推进支付流程的 Android App Links 或 iOS Universal Links。

示例:https://myboost.app.link/IvWm7QZkfjb?%2llback_url=https%3A%2F%2Fmsp.boost-my.com%2Fonlinepayment%2Fauthorise&source=alipay-connect&codeValue=https%3A%2F%2Fglobal.alipay.com%2F2810020400931LFH2t2mq1jjJ8zSetyv31VU

schemeUrl

用于打开支付方式 app 的 scheme URL。

示例:boostapp://inAppDeeplink?deeplink_path=deeplink/onetimepayment&source=alipay-connect&codeValue=https%3A%2F%2Fglobal.alipay.com%2F2810020400931LFH2t2mq1jjJ8zSetyv31VU

注意

  • 在使用如上链接拉起支付时,可能因为买家没有安装支付方式 app 会发生链接跳转的异常,注意异常的处理。
  • 部分支付方式的支付跳转 URL 并不支持多次打开,因此若拉起失败,建议更换 paymentRequestId 重新获取支付链接并拉起。
  • 除了利用跳转 URL 拉起后续支付流程,对于部分支付方式,会在 支付 接口的响应中返回 orderCodeForm 字段,用于提供二维码或支付口令信息。您可以使用 orderCodeForm 字段的值,将支付二维码或支付口令在您网站内的页面上进行渲染来展示给买家,让买家的支付跳转流程保留在商户网站内。关于此方案的详情,请参考 自定义收银台方案

Web 端

在 Web 端场景下,支付 接口的响应中会返回 normalUrl。

URL 打开方式

获取 normalUrl 字段的值后,需要将页面重定向至该支付链接或新页面打开该支付链接。建议您新建一个页面打开该支付链接引导买家完成支付,新建页面代码样例如下:

copy
if (serverResponse.normalUrl != null) {
    window.open(serverResponse.normalUrl, '_blank');
}

用户体验

以 normalUrl 对应的页面是扫码支付或账密登录界面为例,下图展示了 Web 端支付流程的示意图:

扫码支付

image

账密登录支付

image

WAP 端

在 WAP 端场景下,支付 接口的响应中,不同支付方式可能会返回以下三种 URL 中的部分或全部:

  • normalUrl
  • applinkUrl
  • schemeUrl

URL 的使用策略

如果您收到的 支付 接口响应中只返回了三种 URL 中的一种,则直接使用您收到的 URL 作为跳转链接。 如果您收到以上三种 URL 中的多个, 建议按照以下策略使用对应的 URL:

  • iOS 系统:优先使用 applinkUrl,次优使用 schemeUrl,最后选择使用 normalUrl
  • 安卓系统:优先使用 schemeUrl,次优使用 applinkurl,最后选择使用 normalUrl

URL 打开方式

使用 JavaScript 的页面跳转方法。可以使用如下代码打开 URL:

copy
window.location.href = URL;

用户体验

链接类型

支付体验

normalUrl

买家从商户 WAP 页面跳转至支付方式 WAP 页。支付方式 WAP 页面对买家所呈现的内容会因支付方式不同而不同,分为以下几种类型:

  • 账密登录支付页面。后续的支付流程在支付方式 WAP 页内完成。

1-手机浏览器-浏览器支付@3x.png

  • 引导买家点击按钮,用于拉起支付方式 app。后续的支付流程在支付方式 app 内完成。

lQLPJwIAzZIMCqLNBCbNCZCwzBvTFYhPkigEOMrdXUAyAA_2448_1062.png

  • 展示支付口令,买家复制支付口令后打开支付方式 app 并完成支付。

pic1@3x.png

  • 展示付款二维码,买家用手机支付方式 app 扫描二维码完成支付。

pic2@3x.png

applinkUrl

根据买家是否安装支付方式 app,自动决定后续支付流程如何推进:

  • 买家安装了支付方式 app: 打开支付方式 app, 买家在 app 内完成支付。

2-买家安装了支付方式app@3x.png

  • 买家没有安装支付方式 app: 打开 WAP 页面,买家在 WAP 页面按照指引继续完成支付。此流程通过系统默认浏览器打开并渲染跳转链接。

lQLPJwafJWhBSqLNBCbNCZCwWJTLCWXEJ70EOMrdVMAyAA_2448_1062.png

schemeUrl

支付体验取决于买家是否安装了支付方式 app:

  • 买家安装了支付方式 app: 打开支付方式 app, 买家在 app 内完成支付。

3-买家安装了支付方式app@3x.png

  • 买家没有安装支付方式 app: 无法通过此 URL 拉起 app, 买家可能会停留在当前页面无法推进支付。

3-买家未安装支付方式app@3x.png

App 端

在 App 端场景下,支付 接口的响应中,不同支付方式可能会返回以下三种 URL 中的部分或全部:

  • normalUrl
  • applinkUrl
  • schemeUrl

【注意】在 App 端,除了上述用于跳转的 URL 参数,支付 接口的响应中还会返回 appIdentifier 参数,此参数是支付方式 app 对应的包名(package name)。在 app 支付中用于判断支付方式 app 是否安装,还可以用于避免在安卓系统中出现消除歧义框。

URL 的使用策略

如果您收到的 支付 接口响应中,只返回了三种 URL 中的一种,则直接使用您收到的 URL 作为跳转链接。如果您收到以上三种 URL 中的多个, 建议您按照以下顺序使用对应的 URL:

  • iOS 系统:优先使用 applinkUrl,次优使用 schemeUrl,最后选择使用 normalUrl
  • 安卓系统:优先使用 schemeUrl,次优使用 applinkurl,最后选择使用 normalUrl

URL 打开方式

在 iOS 及 Android 系统中,可以通过以下方式打开跳转 URL :

iOS

Android

  • 应用外打开跳转 URL:调用系统方法
  • 应用内打开跳转 URL
    • 使用 WKWebView 控件
    • WKWebView,JSBridge
    • 使用 SafariViewController 组件
  • 判断是否安装支付方式 app 后, 分别采取应用外跳转或应用内打开跳转 URL
  • 应用外打开跳转 URL:调用系统方法
  • 应用内打开跳转 URL
    • 使用 WebView 控件
    • WebView,JavascriptInterface
    • 使用 Custom Tabs 插件
  • 判断是否安装支付方式 app 后, 分别采取应用外跳转或应用内打开跳转 URL

打开方式优缺点对比

每种方式均有其优势,建议您根据自己的系统情况及集成场景选择适合的方案:

打开方式

说明

应用外跳转:调用系统方法打开跳转 URL

Alipay推荐使用此方案

  • 方案优点:适配性更强,集成成本低,一次接入,可兼容所有支付方式及 Alipay 后续支持的更多支付方式。
  • 方案缺点:支付流程会跳出商户应用。

应用内打开跳转 URL

  • WKWebView
  • WebView

WKWebView/WebView 是一个内置的控件,可以在应用程序中嵌入一个 Web 浏览器。你可以使用它来加载网站的链接。

  • 方案优点:您可以定制化支付流程体验,为买家提供更好的支付体验。此外,可以通过此方案实现应用内跳转,即买家不离开商户端应用,在商户应用内完成后续支付流程。
  • 方案缺点:需要更多研发投入与测试。
  • WKWebView+JSBridge
  • WebView+JavascriptInterface

属于基于 WKWebView/WebView 的升级方案,使用 JSBridge/JavascriptInterface 后,WebView 可以直接调用系统方法打开跳转链接。

  • 方案优点:相较 WKWebView/WebView, 性能和安全性有所提升,可以为买家提供更好的定制化支付体验,可扩展性强。
  • 方案缺点:需要更多研发投入与测试。
  • SafariViewController
  • Custom Tabs

是 iOS/Android 官方提供的应用内打开链接的方式,与 WebView 相比,能力更全面。

  • 方案优点:可以和系统浏览器打通,与系统浏览器共用 cookie 等能力。集成方式较为简单。
  • 方案缺点:不支持定制化支付体验。

判断是否安装支付方式 app 后, 分别采取应用外跳转或应用内打开跳转 URL

根据买家是否安装支付方式 app,分别提供不同的跳转链接打开方式。

  • 优点:用户体验好。
  • 缺点:需要更多研发投入与测试。

代码示例(iOS)

方法1: 调用系统方法打开跳转 URL

以下代码示例是通过系统打开 URL 的方式,在 iOS 系统中实现从商户 app 跳转至支付方式 app:

copy
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0) {
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:Url] options:@{} completionHandler:nil];
}else{ 
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:Url]];
}

方法2:应用内打开跳转 URL

当您的业务有客户端,并倾向于在支付流程中使用应用内打开网页的方式进行下单处理,则需要适配所有支付方式。此方案适用于使用以下 URL 类型:

  • normalUrl
  • applinkUrl

【注意】部分支付方式不支持 WAP 页面支付,访问 normalUrl 时会经过重定向并触发 scheme 的跳转来唤醒对应的支付方式 app。WKWebView 会拦截到 scheme 外跳应用,您需要操作 WKWebView 的 decidePolicyForNavigationAction 方法并调用系统方法打开跳转链接,即可实现商户 WKWebView 跳转到支付方式 app 支付。

使用 WKWebView

以下代码示例使用 WKWebView 在 iOS 的应用内加载支付方式页面:

copy
// 初始化 webview 配置
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc]init];
// 初始化 webView 
WKWebView *webView = [[WKWebView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) configuration:configuration];
webView.navigationDelegate = self;
//加载支付方式 URL
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:Url]]];
[self.view addSubview:self.webView];

以下代码示例使用 WKWebView 拦截到 scheme 外跳应用,操作 WKWebView decidePolicyForNavigationAction 方法即可实现商户 WebView 跳转到支付方式 app 支付:

copy
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    // WKWebView 默认拦截 scheme 需用下面方法处理
    // 打开外部应用 Safari 等操作
    NSURL *url = navigationAction.request.URL;
    NSString *absoluteString = url.absoluteString;
    NSString *scheme = url.baseURL.scheme;

    DLog(@"navigationAction.request.URL.absoluteString=====> %@", absoluteString);
    if ([absoluteString isEqualToString:@"about:blank"]) {
        decisionHandler(WKNavigationActionPolicyCancel);
    }
    if (!([absoluteString containsString:@"https://"] || [absoluteString containsString:@"http://"])) {
        if ([absoluteString containsString:@"://"]) {
            NSString *urlHeader =  [absoluteString componentsSeparatedByString:@"://"][0];
            [MBProgressHUD showAutoMessage:[NSString stringWithFormat:@"Scheme\n%@://",urlHeader] toView:self.view];
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self openAppWithUrlStr:navigationAction.request.URL];
                decisionHandler(WKNavigationActionPolicyAllow);
            });
        }
    } else {
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}
使用 WKWebView 及 JSBridge

使用该方法会更加优化买家支付的体验,同时需要较强的开发能力,在通过 WKWebView 打开 URL 的基础上结合使用 JSBridge,有利于项目后续的维护及可扩展性,同时又能提高性能和安全性。使用 JSBridge可以帮助网页和原生应用之间的交互更加方便,实现 WAP 页面可以直接调用 app 的 native 方法。以下代码示例展示了在 WKWebView 中使用 JSBridge 的方法:

copy
[self.wkWebView evaluateJavaScript:bridge completionHandler:nil];
使用 SFSafariViewController

SFSafariViewController 支持 normalUrl, applinkUrl, 及 schemeUrl 的打开及渲染。与 WebView 相比,能力更全面,集成方式较为简单。使用 SFSafariViewController 打开链接的实现方式可参考 iOS 官方提供的 SFSafariViewController 使用文档。以下代码示例展示了使用 SFSafariViewController 的方法:

copy
SFSafariViewController *safariVC = [[SFSafariViewController alloc] initWithURL:Url entersReaderIfAvailable:NO];
safariVC.delegate = self;
[self.navigationController presentViewController:safariVC animated:YES completion:nil];

方法3:判断是否安装支付方式 app 并分别处理

首先需要判断买家是否安装了支付方式 app ,再针对不同情况使用不同的 UR L打开方式进行处理。在 iOS 系统下,需要完成以下步骤:

  1. 在 info.plist 配置中添加 LSApplicationQueriesSchemes 。需注意 info.plist 中对 scheme 有个数限制。

  1. 在代码中通过 canOpenURL 方法判断是否安装了支付方式 app。代码实现请参考以下示例:
copy
NSString *walletSchemeUrl = @"gcash://";

if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:walletSchemeUrl]]){
    // 支付方式应用已安装,建议通过原生方式打开
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:Url] options:@{} completionHandler:nil];
    
    return YES;
} else {
    // 支付方式应用未安装,建议通过 WEBVIEW 加载 H5 页面
    SFSafariViewController *safariVC = [[SFSafariViewController alloc] initWithURL:Url entersReaderIfAvailable:NO];
    safariVC.delegate = self;
    [self.navigationController presentViewController:safariVC animated:YES completion:nil];
    
    return NO;
}

代码示例(Android)

方法1: 调用系统方法打开跳转 URL

以下代码示例是通过系统打开 URL 的方式,在 Android 系统中实现从商户 app 跳转至支付方式 app:

copy
try {
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(Url));
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
    // use the startActivity function to redirect to the wallet app 
    startActivity(intent);
} catch (Exception e) {
    e.printStackTrace();
}

使用此方法可能会出现消除歧义对话框。

什么是消歧对话框?

Android App Link 在安装应用时向谷歌服务器请求身份认证。 如果身份验证失败,则 Android 应用程序链接将失效,并且当买家尝试通过此类链接打开应用程序时会出现消歧对话框。买家需要手动选择如何打开链接。

此图显示了当买家点击 Android 应用程序链接时出现的消歧对话框示例。买家需要手动选择打开链接的方式:使用谷歌地图或谷歌浏览器。

002.png

如何防止消歧对话框出现?

当出现消歧对话框时,买家需要手动选择应用程序的打开方式,影响支付成功率。 因此,您需要防止出现消歧对话框,请执行以下操作之一:

  • 当买家安装了支付方式 app 时,指定支付方式的 packageName,打开支付方式的 URL。
  • 当买家没有安装支付方式 app 时,使用下面的示例代码实现离开商户 app, 并打开跳转 URL:
copy
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(applinkUrl));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
//设置支付方式的包名
intent.setPackage(walletPackageName);
PackageManager packageManager = MainActivity.this.getPackageManager();
//查询是否有支持打开该链接的应用。
List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
if (activities.size() <= 0) {
   //支付方式 app 未安装。请重新初始化 Intent,该链接会由系统默认支持的方式打开。
   intent = new Intent(Intent.ACTION_VIEW, Uri.parse(applinkUrl));
   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     startActivity(intent);
} else {
  //支付方式 app 已安装。通过指定支付方式报名打开支付方式 URL,消除歧义对话框不会出现。  
     startActivity(intent);
}

【注意】 以下列表展示了部分支付方式的 packageName 值:

  • AlipayHK: hk.alipay.wallet
  • GCash: com.globe.gcash.android
  • TrueMoney: th.co.truemoney.wallet
  • KakaoPay: com.kakao.talk
  • Touch 'n Go: my.com.tngdigital.ewallet
  • Dana: id.dana

方法2:应用内打开跳转 URL

当您的业务有客户端,并倾向于在支付流程中使用应用内打开网页的方式进行下单处理,则需要适配所有支付方式,可以使用 WebView 容器加载 normalUrlapplinkUrl:

  • normalUrl: normalUrl 对应的链接为 WAP 页面,直接在 WebView 中打开 WAP 页面,用于完成支付。
  • applinkUrl: 对应的页面为 WAP 页面,直接在 WebView 中打开 WAP 页面,用于完成支付。

【注意部分支付方式不支持 WAP 页面支付, 访问 normalUrl 时会经过重定向并触发 scheme 的跳转来唤醒对应的支付方式 app 。WebView 会拦截到 scheme 外跳应用,您需要操作 WebView 的shouldOverrideUrlLoading 方法并调用系统方法打开跳转链接,即可实现商户 WebView 跳转到支付方式 app 支付。

使用 WebView

以下代码示例使用 WebView 在 Android 的应用内加载支付方式页面:

copy
WebView webView = findViewById(R.id.webview);
//设置 webview 客户端
webView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        view.loadUrl(request.getUrl().toString());
        return super.shouldOverrideUrlLoading(view, request);
    }});

WebSettings webSettings = webView.getSettings();
//启用 javascript
webSettings.setJavaScriptEnabled(true);
//启用 scaling
webSettings.setSupportZoom(true);
//启用 scaling controls (buttons)
webSettings.setBuiltInZoomControls(true);
//Webview 有两种缓存模式,这里不使用缓存加载
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
//允许 JavaScript 打开新窗口 (默认为 false)
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
//允许 JavaScript 加在本地缓存
webSettings.setDomStorageEnabled(true);
//WAP 缓存大小 (无需手动设置)
//webSettings.setAppCacheMaxSize(1024 * 1024 * 8);
//WAP 缓存路径
String absolutePath = getApplicationContext().getCacheDir().getAbsolutePath();
//WAP 缓存大小
webSettings.setAppCachePath(absolutePath);
//是否允许 WebView 访问文件 (默认为 true)
webSettings.setAllowFileAccess(true);
//允许保存 WAP 缓存
webSettings.setAppCacheEnabled(true);
//使用概览模式时,如果页面宽度超过WebView显示,缩放页面以适应WebView(默认为false)
webSettings.setLoadWithOverviewMode(true);
//支持视口 HTML 元标签
webSettings.setUseWideViewPort(true);
//加在支付方式支付 URL
webView.loadUrl(Url);

以下代码示例使用 WebView 拦截到 scheme 外跳应用,通过对 WebView 设置 WebViewClient,使用WebViewClient.shouldOverrideUrlLoading() 方法对 URL 进行拦截,拦截后判断其格式,然后 native 解析到对应的方法和数据后执行本地方法:

copy
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
    if (request.getUrl().toString().startsWith("http")) {
        view.loadUrl(request.getUrl().toString());
        return super.shouldOverrideUrlLoading(view, request);
    } else {
        view.onPause();
        view.stopLoading();
        try {
          Intent intent = Intent.parseUri(uri, Intent.URI_INTENT_SCHEME);
          intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
          view.getContext().startActivity(intent);
        } catch (URISyntaxException e) {
          //提示买家未安装支付方式 app 
        }
        return false;
    }
}

【注意如果您的应用有跳转外部 app 白名单,需注意白名单的处理与配置,考虑旧版兼容性问题并减少应用的发版次数。

使用 WebView 及 JavascriptInterface

如果您研发能力强,且非常重视买家的支付体验,建议在 WevView 中使用 JavascriptInterface。使用JavaScriptInterface 可以帮助 Android 应用程序和 WebView 之间进行双向通信,使得 WAP 页面可以直接调用 app 的 native 方法,让您的应用程序更加灵活和强大,有利于项目后续的维护及扩展。以下代码示例展示了在 WebView 中使用 JavascriptInterface 的方法:

  1. 在 WebView 里声明一个 JavascriptInterface
copy
@JavascriptInterface
    public void openActivity(String url) {
        //根据实际情况添加到代码中
        try {
        Intent intent = Intent.parseUri(uri, Intent.URI_INTENT_SCHEME);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    } catch (Exception e) {
        Toast.makeText(context, "App not installed", Toast.LENGTH_SHORT).show();
    }
}
  1. 给 WebView 设置 JavascriptInterface
copy
mWebView.addJavascriptInterface(this, "bridge");
  1. 使用以下代码对跳转 URL 进行打开
copy
window.bridge.openActivity("Url");
使用 Custom Tabs

Custom Tabs 支持 normalUrl, applinkUrl, 及 schemeUrl 的打开及渲染。与 WebView 相比,能力更全面,集成方式较为简单。以下代码示例展示了使用 Custom Tabs 的方法:

  1. Gradle 项目文件中引入 Custom Tabs
copy
dependencies {
    ...
    implementation "androidx.browser:browser:1.4.0"
}
  1. 使用 Custom Tabs 在应用中打开一个 Chrome Tab
copy
// 使用 CustomTabsIntent.Builder 配置 CustomTabsIntent.
// 准备就绪后,调用 CustomTabsIntent.Builder.build() 来创建 CustomTabsIntent
// 使用 CustomTabsIntent.launchUrl() 启动所需的 URL

CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(this, Uri.parse(url));

更多关于如何使用 CustomTabs 打开链接的信息,请参考 Android 官方提供的 Custom Tabs 使用指南

方法3:判断是否安装支付方式 app 并分别处理

首先需要判断买家是否安装了支付方式 app ,再针对不同情况使用不同的 URL 打开方式进行处理。

在 Android 系统下,此方案的实现需要完成以下步骤:

  1. 出于 Android 系统的隐私和安全政策,需要在 AndroidManifest.xml 中 添加 <queries> 标签,以确保支付链接能打开对应的支付方式 app。<queries> 标签中需要配置支付方式 app 的包名(package name),对应的值可以从 Alipay 的 支付 接口返回中通过 appIdentifier 参数获取,或者联系 Alipay 技术支持。
copy
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          package="com.llw.scandemo">
  
  ...
  <queries>
    <package android:name="th.co.truemoney.wallet" />
    <package android:name="com.eg.android.AlipayGphone" />
    <package android:name="my.com.tngdigital.ewallet" />
    ...
  </queries>
  ...
  
</manifest>
  1. 通过以下代码判断是否安装支付方式 app 并拉起支付:
copy
String Url = "applinkUrl/schemeUrl";
try {
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(Url));
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setPackage("my.com.tngdigital.ewallet");
    // 通过以下两行代码判断是否安装支付方式 app
    PackageManager packageManager = MainActivity.this.getPackageManager();
    List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);
    
    if (activities.size() <= 0) {
        // 支付方式 app 未安装。建议在 WEBVIEW 中打开 H5 链接

        intent = new Intent(MainActivity.this, WebviewActivity.class);
        intent.setData(Uri.parse(Url));
        startActivity(intent);
    } else {
        
        // 支付方式 app 已安装。通过原生方式唤起交易。
        startActivity(intent);
    }
} catch (Exception e) {
    // 处理报错
    e.printStackTrace();
}

用户体验

链接的不同打开方式下所对应的的支付跳转流程如下:

打开方式

支付跳转流程

应用外跳转:调用系统方法打开跳转 URL

应用外跳转。支付体验取决于买家是否安装了支付方式 app:

  • 已安装: 从商户的 app 跳转至支付方式 app。即买家选择完支付方式后,通过 Alipay 返回的 schemeUrlapplinkUrl 直接拉起支付方式 app 进行支付,买家在支付方式 app 上完成支付。

4-1@3x.png

  • 未安装: 从商户的 app 跳转至系统默认浏览器。即:
    • 系统浏览器支付:买家选择完支付方式后,通过Alipay返回的 normalUrlapplinkUrl 从商家 App 跳转到系统默认浏览器打开的支付方式 WAP 页面,买家在此页面上完成登陆支付。

4-2@3x.png

    • 系统浏览器转支付方式 app 支付:买家选择完支付方式后,通过 Alipay 返回的 normalUrlapplinkUrl 从商家 app 跳转到系统默认浏览器打开的支付方式 WAP 页面,支付方式 WAP 页面会唤起支付方式 app,买家在支付方式 app 上完成支付。

4-3@3x.png

应用内打开跳转URL

有应用外跳转及应用内跳转两种支付体验:

  • 商户 WebView 转支付方式 app 支付(应用外跳转):买家选择完支付方式后,通过 Alipay 返回的 normalUrlapplinkUrl 在商家 app 内置的 WebView 进行打开。打开后页面会展示拉起支付方式的 WAP 页面,买家点击唤起支付方式 app 的按钮,此时需要开发者为 WebView 设置处理 scheme 的能力,支付方式 WAP 页面会唤起支付方式 app。买家在支付方式 app 上完成支付。

app-webview.png

  • 商户 WebView 支付(应用内跳转):买家选择完支付方式后,通过Alipay返回的 normalUrlapplinkUrl 在商家 app 内直接拉起支付方式的 WAP 页面,买家可在此页面上完成登陆支付。

5-1@3x.png

最佳实践

建议您根据不同支付方式做打开跳转 URL 的固定配置,或根据支付方式、设备环境和返回内容进行路由。下图展示了根据不同支付方式做固定配置的示例:

支付拉起方式决策过程-1@3x.png

针对每一种支付方式,您在决策使用什么方式打开跳转 URL 时,建议按照以下方式进行判断:

支付拉起方式决策过程-2@3x.png