Swift 内嵌H5跳转微信、支付宝支付问题

需求:swift WKWebView展示H5页面,在H5上点击按钮进行跳转微信app,支付宝app进行支付,支付完成后(无论支付成功与否),返回自己的app刷新当前H5页面;

WKWebView的使用方式就不赘述了,网上一大堆;重点在于拦截点击支付时的操作;当点击H5按钮进行支付时,需要拦截H5的请求操作,进行跳转app。

具体代码如下:实现 WKWebView的代理方法:

  func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void){

    let urlScheme = navigationAction.request.url?.scheme ?? ""
    let urlStr = navigationAction.request.url?.absoluteString ?? ""
    
    // 此处拦截支付宝支付
    if urlScheme == "alipay" || urlScheme == "alipays" {
            
        // 此处是为处理支付宝支付链接的 scheme(解决支付完成后无法返回app的问题)
        let aliPayUrl = handleAlipayUrl(url: navigationAction.request.url!)

        if UIApplication.shared.canOpenURL((aliPayUrl ?? URL(string: "0"))!) {
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(aliPayUrl!, options: [:], completionHandler: nil)
            } else {
                UIApplication.shared.openURL(aliPayUrl!)
            }
            
            decisionHandler(WKNavigationActionPolicy.cancel)
            return
        } else {
            self.webView.load(navigationAction.request)
            decisionHandler(WKNavigationActionPolicy.allow)
        }
    } else {

        var request = navigationAction.request
        let payUrl = request.url!
        // 此处拦截微信支付
        if urlStr.contains("wx.tenpay.com") && request.value(forHTTPHeaderField: "Referer") != "pay.dassoft.cn://" {
            decisionHandler(WKNavigationActionPolicy.cancel)
            request.setValue("pay.dassoft.cn://", forHTTPHeaderField: "Referer")
            self.webView.load(request)

        } else {

            if urlScheme == "weixin" {
                if payUrl.host == "wap" {
                    if payUrl.relativePath == "/pay" {
                        if UIApplication.shared.canOpenURL(payUrl) {
                            if #available(iOS 10.0, *) {
                                UIApplication.shared.open(payUrl, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([convertFromUIApplicationOpenExternalURLOptionsKey(UIApplication.OpenExternalURLOptionsKey.universalLinksOnly): false]), completionHandler: nil)
                            } else {
                                UIApplication.shared.openURL(payUrl)
                            }
                        }
                    }
                }
            }
            decisionHandler(WKNavigationActionPolicy.allow)
        }
    }
} 

fileprivate func handleAlipayUrl(url: URL) -> URL? {
    
    if url.absoluteString.hasPrefix("alipay://alipayclient/") {
        // 更换scheme
        var decodePar = url.query ?? ""
        decodePar = decodePar.urlDecoded()
        var dict = self.stringValueDic(decodePar)
        dict?["fromAppUrlScheme"] = "你app的scheme"
        if let strData = try? JSONSerialization.data(withJSONObject: dict as Any , options: []) {
            var param = String(data: strData, encoding: .utf8)
            param = param?.urlEncoded()
            let finalStr = "alipay://alipayclient/?\(param ?? "")"
            return URL(string:finalStr)
        }
        return url
    }
    return nil
}


func stringValueDic(_ str: String) -> [String : Any]?{
    let data = str.data(using: String.Encoding.utf8)
    if let dict = try? JSONSerialization.jsonObject(with: data!,
                    options: .mutableContainers) as? [String : Any] {
        return dict
    }

    return nil
}


//扩展类
extension String {
//将原始的url编码为合法的url
func urlEncoded() -> String {
    let encodeUrlString = self.addingPercentEncoding(withAllowedCharacters:
        .urlQueryAllowed)
    return encodeUrlString ?? ""
  }
 
//将编码后的url转换回原始的url
func urlDecoded() -> String {
    return self.removingPercentEncoding ?? ""
  }
}

你可能感兴趣的:(Swift 内嵌H5跳转微信、支付宝支付问题)