Alipay+ DocsAlipay+ Docs

Guide on redirections between the merchant and the digital wallet

1. Overview

For Alipay+ Auto Debit, redirections between the merchant and the digital wallet occur during the authorization process.

For Alipay+ Cashier Payment, redirections between the merchant and the digital wallet occur during the payment process.

This document explains how the redirections work on Android, iOS, and Web sides, and provides best practices on how to handle the redirections in different scenarios.

1.1 Process

This section describes the redirection processes for Auto Debit and Cashier Payment in detail.

1.1.1 Auto Debit

The following figure illustrates the redirection process:

Guide on redirections between the merchant and the digital wallet

For Auto Debit, redirections occur during the authorization process. See the following list for the process breakdown:

  1. On the merchant side, the user selects a wallet to authorize. The merchant sends the authorization info to the Acquiring Service Provider (ACQP) (Step 1 - 3).
  2. The ACQP uses prepare interface to obtain the authorization URL (Step 4 - 10). authRedirectUrl must be included in the request, which is used to redirect the user back to the merchant at the user completes the authorization.
  3. The merchant system redirects the user to the authorization page specified by the authorization URL (Step 11).
  4. The wallet system renders the authorization page, where the user completes the authorization (Step 12 - 13).
  5. The wallet processes the authorization and redirects the user back to the merchant page specified by authRedirectUrl (Step 14 - 16). The authorization code (authCode) is attached in the authRedirectUrl (Step 14 - 16).
  6. With the authCode, the merchant system uses applyToken interface to obtain accessToken, which is used to debit funds from the user's authorized wallet (Step 17 - 24).

1.1.2 Cashier Payment

The following figure illustrates the redirection process:

Guide on redirections between the merchant and the digital wallet

For Cashier Payment, redirections occur during the payment process. See the following list for the process breakdown:

  1. On the merchant side, the user selects a wallet to pay. The merchant sends the payment order info to the ACQP (Step 1 - 3).
  2. The ACQP uses pay interface to send the payment request to Alipay+ (Step 4). paymentRedirectUrl must be included in the request, which is used to redirect the user back to the merchant after the payment is completed.
  3. Alipay+ processes the request and returns the payment URL to the merchant (Step 5 -9).
  4. The merchant redirects the user to the cashier page specified by the payment URL, where the user pays (Step 10 - 12).
  5. The wallet processes the payment and redirects the user back to the merchant page specified by paymentRedirectUrl (Step 14 - 16).

Note:

When the terminal type of the merchant is Web, and if the order code is merchant-rendered QR code, no redirection occurs.

For more information about limitations for redirection, see section 1.2.

1.2 Client type and redirections

For both Auto Debit and Cashier Payment, the redirections always occur in 2 stages:

  1. The user is redirected from the merchant side to the wallet side.
  2. The user is redirected from the wallet side back to the merchant side.

For Auto Debit, both redirections must succeed. For Cashier Payment, the second redirection does not affect the payment result.

Furthermore, the merchant client and the wallet client can be either app, WAP, or Web. However, redirections can only happen between certain terminal types of client-side. See the following sections for details.

1.2.1 Auto Debit

  1. Redirection from the merchant to the wallet:

From

merchant

To digital wallet

App

WAP

Web

App

✅ Supported.

✅ Supported.

Used when the digital wallet app is not available.

N/A

WAP

Forbidden.

The user can be only redirected from the merchant's WAP page to the wallet's WAP page. Otherwise, when redirecting the user back from an app to a WAP page, the user login info might be lost and result in authorization failure.

✅ Supported.

N/A

Web

N/A

N/A

✅ Supported.

  1. Redirection from the wallet back to the merchant:

From

digital wallet

To merchant

App

WAP

Web

App

✅ Supported.

N/A

The user can only be redirected from the merchant's WAP page to the wallet's WAP page, therefore, the redirection-back from the wallet app to the merchant WAP client will not occur.

N/A

WAP

✅ Supported.

Used when the digital wallet app is not available.

✅ Supported.

N/A

Web

N/A

N/A

✅ Supported.

1.2.2 Cashier Payment

  1. Redirection from the merchant to the wallet:

From

merchant

To digital wallet

App

WAP

Web

App

✅ Supported.

✅ Supported.

Used when the digital wallet app is not available.

N/A

WAP

✅ Supported.

Not recommended. The redirection-back from an app to a WAP page might lose the user login info and the payment result page might not be able to display.

✅ Supported.

N/A

Web

N/A

N/A

✅ Supported.

  1. Redirection from the wallet back to the merchant:

From

digital wallet

To merchant

App

WAP

Web

App

✅ Supported.

✅ Supported.

Not recommended. The redirection-back from an app to a WAP page might lose the user login info and the payment result page might not be able to display.

N/A

WAP

✅ Supported.

Used when the digital wallet app is not available.

✅ Supported.

N/A

Web

N/A

N/A

✅ Supported.

Note:

When the terminal type of the merchant is Web, and if the order code is merchant-rendered QR code, no redirection occurs.

2. Alipay+ redirection standards

2.1 Basic conceptions

2.1.1 Deep linking

In the context of Web development, deep linking is the use of a hyperlink that links to a specific, generally searchable or indexed, piece of Web content on a website (e.g. http://example.com/my-awesome-content-page ), rather than the website's home page (e.g. http://example.com).

In the context of mobile development, deep linking refers to directly linking to in-app content using a hyperlink.

For Auto Debit, the redirection uses deep linking to redirect the user from the merchant side to the authorization page on the digital wallet side while retaining the context about the authorization.

For Cashier Payment, the redirection uses deep linking to redirect the user from the merchant side to the payment page on the digital wallet side, while retaining the context of the payment.

2.1.2 URL scheme, Universal Link, and App Link.

URL scheme, Universal Link, and App Link are ways to realize deep linking.

URL scheme is the part of a URI that specifies the app your device uses to open a URL. In the context of mobile development, URL schemes (more precisely, custom URL schemes) allow users to open your app from other apps or WAP pages. However, the URL scheme has some inherent limitations:

  • Errors occur if the app to be opened is not installed.
  • You cannot decide which app to open if multiple schemes with the same name are registered.

To solve these problems, iOS uses Universal Link. Android uses App Link. You can visit the pages in the hyperlinks to learn more about them.

2.1.3 Alipay+ URL types

Alipay+ uses schemeUrl, applinkUrl, and normalUrl.

  • schemeUrl represents URL schemes.
  • applinkUrl represents Universal Links and App Links.
  • normalUrl represents the ordinary Web/WAP URL that redirects users to a Web/WAP page.

See section 2.2.1 for details.

2.2 Alipay+ redirection fields

2.2.1 Fields for redirection to the wallet

For both Cashier Payment and Auto Debit, when the ACQP requests the redirection URL, Alipay+ returns up to 4 of the following fields:

No.

Field

Description

1

schemeUrl

Optional String (2048)

The URL scheme that redirects users to open an APP. Only works if the target app is installed.

2

applinkUrl

Optional String (2048)

The URL that redirects users to open an APP, or, if no APP is installed, to a WAP page. For Android, this field is the native App Link, and for iOS, the Universal Link.

3

normalUrl

Optional String (2048)

The Web/WAP URL that redirects users to a Web/WAP page in the browser or the WebView.

4

appIdentifier

OPTIONAL String

Android package name.

Note: Required when the osType is ANDROID.

For details about these fields, see the corresponding interfaces for each product:

  • Auto Debit: prepare interface.
  • Cashier Payment: pay interface.

Notes:

  • When result.resultCode is SUCCESS, schemeUrl, applinkUrl, and normalUrl cannot all be null.
  • For priorities of which URL to use for the redirection to the wallet side, schemeUrl > applinkUrl > normalUrl.
  • In some scenarios (for example, when terminalType=WEB/WAP and the terminal cannot handle the schemeUrl or applinkUrl), Alipay+ only returns normalUrl.

2.2.2 Fields for redirection back to the merchant

The fields for redirection back to the merchant are provided in the interface request, specifically:

  • authRedirectUrl for Auto Debit, in the prepare interface request.
  • paymentRedirectUrl for Cashier Payment, in the pay interface request.

The merchant must determine the type of these URLs according to the merchant side environment, specifically:

  • If the merchant side is the merchant's app, use schemeUrl or applinkUrl.
  • If the merchant side is browsers or other apps, use applinkUrl or normalUrl.

3. Best practices for redirections between mobile terminals

Alipay+ has designed the best practices for the integration scenarios for Android, iOS, and WAP respectively. This section focuses on ensuring that:

  • The redirection to the digital wallet app takes top priority.
  • The redirection to the digital wallet side can succeed even if the redirection to the digital wallet app fails.

3.1 Android

To ensure that the redirection from the merchant Android side to the digital wallet side can succeed, Alipay+ has designed the best practices for 3 integration scenarios.

  • Scenario 1: The ACQP sends the redirection URL to the merchant directly. If the wallet app cannot be opened, redirect the user to the wallet WAP page in an external browser.
  • Scenarios 2: The ACQP sends the redirection URL to the merchant directly. If the wallet app cannot be opened, redirect the user to the wallet WAP page in the WebView.
  • Scenarios 3: The merchant side uses WebView to open the ACQP's intermediate page, where the redirection to the digital wallet side occurs.

The best practices are specific for Android, see the following sections for details.

3.1.1 Redirection to WAP page in an external browser after redirection to wallet app fails

Prerequisite: No intermediate page. The ACQP directly passes Alipay+ response message to the merchant.

In this scenario, the merchant app can obtain the redirection URL to the wallet side. If the wallet app cannot be opened, redirect the user to the wallet WAP page in an external browser.

To ensure the redirection success, use the following strategy:

Android场景1.png

Sample code:

copy
        Intent request = getIntent();
        // Digital wallet URL
        String applinkUrl    = request.getStringExtra("applinkUrl");
        String schemeUrl     = request.getStringExtra("schemeUrl");
        String normalUrl     = request.getStringExtra("normalUrl");
        String appIdentifier = request.getStringExtra("appIdentifier");

        if (StringUtils.isNotBlank(schemeUrl)) {
            // Specify the package and invoke the scheme. No pop-up window.
            if (openWithPackageName(schemeUrl, appIdentifier)) {
                return;
            }
        }
        // scheme is not invoked, use applink
        if (StringUtils.isNotBlank(applinkUrl)) {
            // Specify the package and invoke the applink. No pop-up window.
            if (openWithPackageName(applinkUrl, appIdentifier)) {
                return;
            }
            // Open the applink with default browser. No pop-up window.
            if (openWithDefaultBrowser(applinkUrl)) {
                return;
            }
            // Can select a browser to open the applink. Use a pop-up window.
            if (openWithDefaultBrowserPopup(applinkUrl)) {
                return;
            }
        }
        // applink is not invoked, use normalUrl
        if (StringUtils.isNotBlank(normalUrl)) {
            // Open the normalUrl with default browser. No pop-up window.
            if (openWithDefaultBrowser(normalUrl)) {
                return;
            }
            // Can select a browser to open the normalUrl. Use a pop-up window.
            if (openWithDefaultBrowserPopup(normalUrl)) {
                return;
            }
        } else {
            // No application can process the HTTP link. This occurs in situations such as when all browsers are uninstalled.
            return;
        }

3.1.2 Redirection to WAP page in WebView after redirection to wallet app fails

Prerequisite: No intermediate page. The ACQP directly passes Alipay+ response message to the merchant.

In this scenario, the merchant app can obtain the redirection URL to the wallet side. If the wallet app cannot be opened, redirect the user to the wallet WAP page in the WebView.

To ensure the redirection success, use the following strategy:

Android场景2.png

Sample code:

copy
        Intent request = getIntent();
        // Digital wallet URL
        String applinkUrl    = request.getStringExtra("applinkUrl");
        String schemeUrl     = request.getStringExtra("schemeUrl");
        String normalUrl     = request.getStringExtra("normalUrl");
        String appIdentifier = request.getStringExtra("appIdentifier");

        if (StringUtils.isNotBlank(schemeUrl)) {
            // Specify the package and invoke the scheme. No pop-up window.
            if (openWithPackageName(schemeUrl, appIdentifier)) {
                return;
            }
        }
        // scheme is not invoked, use applink
        if (StringUtils.isNotBlank(applinkUrl)) {
            // Specify the package and invoke the applink. No pop-up window.
            if (openWithPackageName(applinkUrl, appIdentifier)) {
                return;
            }
            // Open the applink in Webview as an WAP page.
            if (openWithWebView(applinkUrl)) {
                return;
            }
        }
        // applink is not invoked, use normalUrl
        if (StringUtils.isNotBlank(normalUrl)) {
            // normalUrl can always be open in Webview
            if (openWithWebView(normalUrl)) {
                return;
            }
        } else {
            // N/A
            return;
        }

3.1.3 Redirection via the intermediate page

Prerequisite: Use the ACQP's intermediate page. Use the intermediate page URL to pass the urlType and appIdentifier to the merchant.

In this scenario, the merchant app can use WebView to open the ACQP's intermediate page, where the redirection to the digital wallet side occurs. The WebView must be able to identify the urlType and appIdentifier, and opens the applinkUrl or the schemeUrl.

When the intermediate page URL is loaded in the WebView, intercept the redirection and check if the required info (urlType and appIdentifier) is in the URL.

To ensure the redirection success, use the following strategy:

Android场景3.png

Sample code:

copy

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view);

        Intent request = getIntent();
        // Acquiring Partner's intermediate page URL, not the digital wallet URL.
        String url = request.getStringExtra("url");

        WebView webview = (WebView) findViewById(R.id.jhwebview);
        webview.setWebViewClient(createWebViewClient());
        webviewSettings(webview);

        webview.loadUrl(url);
    }

    /**
     * Rewrite the WebView implementation
     *
     * @return
     */
    private WebViewClient createWebViewClient() {

        WebViewClient webViewClient = new WebViewClient() {

            @Override
            public boolean shouldOverrideUrlLoading(WebView wv, String url) {

                if (url == null) {
                    return false;
                }

                try {
                    if (url.startsWith("https://") || url.startsWith("http://")) {
                        // Can be either applinkUrl or normalUrl.

                        String urlType       = UriUtils.getQueryParameter(url, "urlType");
                        String appIdentifier = UriUtils.getQueryParameter(url, "appIdentifier");

                        switch (urlType) {
                            case "applinkUrl":
                                // Specify the package and invoke the applink. No pop-up window.
                                if (openWithPackageName(url, appIdentifier)) {
                                    return true;
                                }
                                // App is not installed. Open as WAP in WebView.
                                wv.loadUrl(url);
                                return true;
                            case "schemeUrl":// Not actually runned.
                                // Specify the package and invoke the applink. No pop-up window.
                                openWithPackageName(url, appIdentifier);
                            case "normalUrl":
                            default:
                                wv.loadUrl(url);
                                return true;
                        }
                    } else {
                        // schemeUrl
                        openWithPackageName(url, null);
                        return true;
                    }
                } catch (Exception e) {
                    // For example, no app can process the scheme.
                    toast(e.getLocalizedMessage());
                    return true;
                }
            }
        };
        return webViewClient;
    }

    /**
     * Webview settings
     *
     * @param webView
     */
    private void webviewSettings(WebView webView) {

        WebSettings webSettings = webView.getSettings();
        //Enable javascript
        webSettings.setJavaScriptEnabled(true);
        //Enable scaling
        webSettings.setSupportZoom(true);
        //Enable scaling controls (buttons)
        webSettings.setBuiltInZoomControls(true);
        //2 cache mode for WebView (web and WAP). Load no cache here.
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        //Allow JavaScript to open new windows (false by default).
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        //Allow JavaScript to load the local cache.
        webSettings.setDomStorageEnabled(true);
        //WAP cache size (No need to manually set)
        //webSettings.setAppCacheMaxSize(1024 * 1024 * 8);
        //WAP cache path
        String absolutePath = getApplicationContext().getCacheDir().getAbsolutePath();
        ///WAP cache size
        webSettings.setAppCachePath(absolutePath);
        //Whether allow WebView to access files (true by default)
        webSettings.setAllowFileAccess(true);
        //Enable to save WAP cache
        webSettings.setAppCacheEnabled(true);
        //When using overview mode, if the the page width exceeds WebView dispaly, scale the page to adapt to the WebView (false by default)
        webSettings.setLoadWithOverviewMode(true);
    }

    private void openWithPackageName(String url, String packageName) {
        try {
            Intent intent= new Intent(Intent.ACTION_VIEW,Uri.parse(url));
            if (!TextUtils.isEmpty(packageName)) {
                intent.setPackage(packageName);
            }
            startActivity(intent);
            return true;
        } catch (Exception exception) {
            return fasle;
        }
    }

3.2 iOS

To ensure that the redirection from the merchant iOS side to the digital wallet side can succeed, Alipay+ has designed the best practices for 3 integration scenarios.

  • Scenario 1: The ACQP sends the redirection URL to the merchant directly. If the wallet app cannot be opened, redirect the user to the wallet WAP page in an external browser.
  • Scenarios 2: The ACQP sends the redirection URL to the merchant directly If the wallet app cannot be opened, redirect the user to the wallet WAP page in the WebView.
  • Scenarios 3: The merchant side can use WebView to open the ACQP's intermediate page, where the redirection to the digital wallet side occurs.

The best practices are specific for iOS, see the following sections for details.

3.2.1 Redirection to WAP page in an external browser after redirection to wallet app fails

Prerequisites:

  • No intermediate page. The ACQP directly passes Alipay+ response message to the merchant.
  • To use the schemeUrl, you must add the schemeUrl to the merchant app's whitelist (LSApplicationQueriesSchemes). See the figure below for a better illustration:

image

In this scenario, the merchant app can obtain the redirection URL to the wallet side. If the wallet app cannot be opened, redirect the user to the wallet WAP page in an external browser.

To ensure the redirection success, use the following strategy:

iOS场景1.png

Sample code:

copy
// The following urls are fetch from Wallet.

NSString *applinkUrl = @"Your AppLinkUrl";
NSString *schemeUrl = @"Your SchemeUrl";
NSString *normalUrl = @"Your NormalUrl";
NSString *targetUrl;

UIApplication *application = [UIApplication sharedApplication];

if ([application canOpenURL:[NSURL URLWithString:schemeUrl]]) {
    targetUrl = schemeUrl;
} else if ([application canOpenURL:[NSURL URLWithString:applinkUrl]]) {
    targetUrl = applinkUrl;
} else {
    targetUrl = normalUrl;
}


// applink or scheme
if (@available(iOS 10.0, *)) {
    [application openURL:[NSURL URLWithString:targetUrl] options:@{} completionHandler:^(BOOL success) {
        if (success) {
            // do something.
        }
    }];
} else {
    [application openURL:[NSURL URLWithString:targetUrl]];
}

3.2.2 Redirection to WAP page in WebView after redirection to wallet app fails

Prerequisites:

  • No intermediate page. The ACQP directly passes Alipay+ response message to the merchant.
  • To use the schemeUrl, you must add the schemeUrl to the merchant app's whitelist (LSApplicationQueriesSchemes). See the figure below for a better illustration:

image

In this scenario, the merchant app can obtain the redirection URL to the wallet side. If the wallet app cannot be opened, redirect the user to the wallet WAP page in the WebView.

To ensure the redirection success, use the following strategy:

iOS场景2.png

Sample code:

copy
// Place following code for init webView to right place.
//    self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds];
//    [self.view addSubview:_webView];

NSString *applinkUrl = @"Your AppLinkUrl";
NSString *schemeUrl = @"Your SchemeUrl";
NSString *normalUrl = @"Your NormalUrl";

UIApplication *application = [UIApplication sharedApplication];

if ([application canOpenURL:[NSURL URLWithString:schemeUrl]]) {
    if (@available(iOS 10.0, *)) {
        [application openURL:[NSURL URLWithString:schemeUrl] options:@{} completionHandler:^(BOOL success) {
            if (success) {
                // do something.
            }
        }];
    } else {
        [application openURL:[NSURL URLWithString:schemeUrl]];
    }
} else if ([application canOpenURL:[NSURL URLWithString:applinkUrl]]) {
    // applink.
    if (@available(iOS 10.0, *)) {
        [application openURL:[NSURL URLWithString:applinkUrl] options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @YES} completionHandler:^(BOOL success) {
            if (success) {
                // do something.
            } else {
                // Can't open universal link directly, it might not install related App.
                NSURL *url = [NSURL URLWithString:applinkUrl];
                NSURLRequest *request = [NSURLRequest requestWithURL:url];
                [self.webView loadRequest:request];
            }
        }];
    } else {
        NSURL *url = [NSURL URLWithString:applinkUrl];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        [self.webView loadRequest:request];
    }

} else {
    // normal url.
    NSURL *url = [NSURL URLWithString:normalUrl];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
}

3.1.3 Redirection via the intermediate page

Prerequisite: Use the ACQP's intermediate page. Use the intermediate page URL to pass the urlType to the merchant.

In this scenario, the merchant app can use WebView to open the ACQP's intermediate page, where the redirection to the digital wallet side occurs. The WebView must be able to identify the urlType, and opens the applinkUrl or the schemeUrl.

When the intermediate page URL is loaded in the WebView, intercept the redirection and check if the required info is in the URL. If the urlType contains applinkUrl or schemeUrl, try redirecting the user to the merchant app directly.

To ensure the redirection success, use the following strategy:

iOS场景3.png

copy
- (void)viewDidLoad {
    //...
    // Sets your web view delegate to appropriate place and implement protocol method like below.
    self.webView.navigationDelegate = self;
}

#pragma mark - WKNavigationDelegate

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSString *scheme = [webView.URL scheme];
    NSString *query = [webView.URL query];
    NSURL *directUrl;
    
    if (scheme) {
        if (![scheme isEqualToString:@"https"] && ![scheme isEqualToString:@"http"]) {
            // Scheme URL
            directUrl = webView.URL;
        } else if (query.length && [query containsString:@"urlType"]) {
            // Parse query to NSDictionary
            NSMutableDictionary *queryStringDict = [[NSMutableDictionary alloc] init];
            NSArray *urlComponents = [query componentsSeparatedByString:@"&"];
            
            for (NSString *kv in urlComponents)
            {
                NSArray *pairComponents = [kv componentsSeparatedByString:@"="];
                NSString *key = [[pairComponents firstObject] stringByRemovingPercentEncoding];
                NSString *value = [[pairComponents lastObject] stringByRemovingPercentEncoding];

                [queryStringDict setObject:value forKey:key];
            }
            
            NSString *urlType = [queryStringDict objectForKey:@"urlType"];
            
            // Applink or Scheme URL
            if ([urlType isEqualToString:@"applinkUrl"]) {
                directUrl = webView.URL;
            }
        }
        
        if (directUrl) {
            UIApplication *application = [UIApplication sharedApplication];
            // scheme
            if (@available(iOS 10.0, *)) {
                [application openURL:directUrl options:@{UIApplicationOpenURLOptionUniversalLinksOnly: @YES} completionHandler:^(BOOL success) {
                    if (success) {
                        // do something.
                    }
                }];
            }
        }
    }
    
    decisionHandler(WKNavigationActionPolicyAllow);
}

3.3 Mobile browser

If only the browser is available on the merchant side, it is recommended to use callapp.js for URL redirections. On the other hand, since the front side cannot determine whether the wallet app is opened when redirecting the user with applinkUrl and schemeUrl, always load normalUrl after applinkUrl/schemeUrl invoking.

To ensure the redirection success, use the following strategy:

前端处理多URL.png

Sample code:

copy
export const openWalletApp = (schemeUrl, applinkUrl, normalUrl, appIdentifier) => {

    if (applinkUrl != null) {
        callapp.gotoPage(applinkUrl, appIdentifier);
    } else if(schemeUrl != null){
        callapp.gotoPage(schemeUrl, appIdentifier);
    }
    window.location.href = normalUrl;
}

callapp.js

copy
// file callapp.js
const callapp = {};
let ua = '';
ua = window.navigator.userAgent;
// Determine the os system version
let isAndroid = false;
let isIOS = false;
let osVersion = '';
let matched = ua.match(/Android[\s\/]([\d\.]+)/);
if (matched) {
  isAndroid = true;
  osVersion = matched[1];
} else if (ua.match(/(iPhone|iPad|iPod)/)) {
  isIOS = true;
  matched = ua.match(/OS ([\d_\.]+) like Mac OS X/);
  if (matched) {
    osVersion = matched[1].split('_').join('.');
  }
}
// compare the os system version
function verCompare(a, b) {
  const v1 = a.split('.');
  const v2 = b.split('.');
  for (let i = 0; i < v1.length || i < v2.length; i += 1) {
    const n1 = parseInt(v1[i], 10) || 0;
    const n2 = parseInt(v2[i], 10) || 0;
    if (n1 < n2) {
      return -1;
    } else if (n1 > n2) {
      return 1;
    }
  }
  return 0;
}
// Determine the type of the browser
let isChrome = false;
let isSafari = false;
let isWebview = false;
if (ua.match(/(?:Chrome|CriOS)\/([\d\.]+)/)) {
  isChrome = true;
  if (ua.match(/Version\/[\d+\.]+\s*Chrome/)) {
    isWebview = true;
  }
} else if (ua.match(/iPhone|iPad|iPod/)) {
  if (ua.match(/Safari/) && ua.match(/Version\/([\d\.]+)/)) {
    isSafari = true;
  } else if (ua.match(/OS ([\d_\.]+) like Mac OS X/)) {
    isWebview = true;
  }
}
const doc = window.document;
let iframe;
function callInIframe(url) {
  console.log('in iframe func', url);
  if (!iframe) {
    console.log('create iframe');
    iframe = doc.createElement('iframe');
    iframe.id = `callapp_iframe_${Date.now()}`;
    iframe.frameborder = '0';
    iframe.style.cssText = 'display:none;border:0;width:0;height:0;';
    doc.body.appendChild(iframe);
  }
  iframe.src = url;
}
function useAnchorLink(url) {
  const a = doc.createElement('a');
  a.setAttribute('href', url);
  a.style.display = 'none';
  doc.body.appendChild(a);
  const e = doc.createEvent('HTMLEvents');
  e.initEvent('click', false, false);
  a.dispatchEvent(e);
}
/**
 * Determine whether the schema is a URL
 * @param  {[type]}  str [schema param]
 * @return {Boolean}     [description]
 */
function isUrl(str) {
  return /^(http|https)\:\/\//.test(str);
}
callapp.gotoPage = function gotoPage(url, packageName, forceIntent) {
  let targetUrl = url;
  console.log('targetUrl', url);
  // intent protocol reference: https://developer.chrome.com/multidevice/android/intents
  // Standard Android Chrome Browser(include the android native chrome browser)need to use intent protocol
  const isOriginalChrome = isAndroid && isChrome && !isWebview;
  // Samsung 4.3/4.4 machine,the native browsers need intent protocol
  const fixUgly = isAndroid && !!ua.match(/samsung/i) && verCompare(osVersion, '4.3') >= 0 && verCompare(osVersion, '4.5') < 0;
  // We need the href of A link on IOS 9.0 and above
  const ios9SafariFix = isIOS && verCompare(osVersion, '9.0') >= 0 && isSafari;
  console.log('isOriginalChrome', isOriginalChrome);
  console.log('fixUgly', fixUgly);
  console.log('ios9SafariFix', ios9SafariFix);
  console.log('forceIntent', forceIntent);
  if (isOriginalChrome || !!forceIntent) {
    // use the intent protocol in the chrome
    const protocol = targetUrl.substring(0, targetUrl.indexOf('://'));
    const hash = `#Intent;scheme=${protocol};package=${packageName};end`;
    targetUrl = targetUrl.replace(/.*?\:\/\//, 'intent://');
    targetUrl += hash;
    console.log('Intent', targetUrl);
  }
  if (ios9SafariFix) {
    if (isUrl(targetUrl)) {
      console.log('not schema');
      return;
    }
    setTimeout(() => {
      useAnchorLink(targetUrl);
    }, 100);
  } else if (targetUrl.indexOf('intent:') === 0) {
    console.log('jump intent');
    setTimeout(() => {
      window.location.href = targetUrl;
    }, 100);
  } else {
    // we can't use intent protocol in the iframe
    const reg = /^(http(s)?\:|javascript\:|vbscript\:|file\:|data\:|sms\:|smsto\:|tel\:|mailto\:|aliim\:|dingtalk\:|weixin\:)/;
    if (!reg.test(targetUrl.toLocaleLowerCase())) {
      console.log('call in iframe');
      callInIframe(targetUrl);
    } else {
      console.log('schema is url');
    }
  }
};
module.exports = callapp;