我们使用的是WKWebView,在下面方法做的一系列的操作
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)
1、全部代码
/// 准备加载
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
let url = webView.url!.absoluteString
print("====>\(url)")
var valueStr = “m.r***n.com://"
if NetworkManager.commonUrl.contains("api.") {
valueStr = "api.r***n.com://"
}
// 从微信回来会自动调用加载redirect_url
if url == valueStr {
return
}
var finalStr = ""
if url.hasPrefix("https://wx.tenpay.com/") && redirect_url.length == 0 {
let absoluteString = webView.url?.absoluteString
if (absoluteString?.contains("https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?"))! {
// 保存并替换redirect_url
if let strArray = absoluteString?.components(separatedBy: "&") {
for i in 0..<strArray.count {
if !strArray[i].contains("redirect_url") {
if finalStr == "" {
finalStr = "\(strArray[i])"
}else {
finalStr = "\(finalStr)&\(strArray[i])"
}
}
}
}
finalStr += "&redirect_url=\(valueStr)"
print("finalStr:", finalStr)
redirect_url = (absoluteString?.components(separatedBy: "=").last)!.removingPercentEncoding!
}
// 设置 Referer
var request:URLRequest = NSURLRequest.init(url: URL.init(string: finalStr)!) as URLRequest
request.httpMethod = "Get"
request.setValue(valueStr, forHTTPHeaderField: "Referer")
webView.load(request)
}
if url.hasPrefix("weixin://wap/pay") {
print("-------需要打开的url:", url)
let urlUrl = URL.init(string: url)
let canOpen = UIApplication.shared.canOpenURL(urlUrl!)
if canOpen {
UIApplication.shared.openURL(urlUrl!)
}else {
showMessage(msg: "未安装相关应用"
}
// 刷新当前页面
let request: URLRequest = NSURLRequest.init(url: URL.init(string: redirect_url)!) as URLRequest
webView.load(request)
redirect_url = ""
}
}
2、H5吊起微信客户端支付
1>m.r***n.com/api.r***n.com为你们公司在微信后台注册的一级域名,因为我们有正式环境和测试环境,所以对于这个值我做了判断。
2>微信支付,中间会调用两个关键的url
URL1: https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx***&package=***&redirect_url=***
URL2: weixin://wap/pay?prepayid%3D***&package=***&noncestr=***&sign=***
把URL1修改为如下:
https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx***&package=***&redirect_url=api.r***n.com://
注意:如果你的url中有redirect_url,需要将值替换成 “一级域名:// ”,如果没有需要添加这个参数,因为微信支付成功会默认调用redirect_url,如果这个值是http...的回调地址,就会打开Safari。
3>拦截到"weixin://wap/pay"",则手动吊起微信APP,判断是否可以吊起,如果掉不起,则提示未安装该应用;
4>需要在改方法前面添加一步判断,如果当前的url是“一级域名:// ”,则直接返回就可以了,因为在吊起微信的时候,我们手动加载了完成页面。
// 从微信回来会自动调用加载redirect_url
if url == valueStr {
return
}
5>我们手动加载的完成页面如下图,点击返回,跳转我的订单页面。
3、支付成功/失败,返回Safari的问题解决
1>在request中添加 Referer 参数
// 设置 Referer
var request:URLRequest = NSURLRequest.init(url: URL.init(string: finalStr)!) as URLRequest
request.httpMethod = "Get"
request.setValue(valueStr, forHTTPHeaderField: "Referer")
webView.load(request)
2>替换 redirect_url 的值为 “一级域名:// ”
我们的URL1中有回调地址,我把这个回调地址进行了保存,吊起微信的时候,手动在当前页面加载回调地址,从微信支付成功或者失败都显示回调地址地址页面,如果不进行保存,当前页面也会自动加载回调地址,不过当前的回调地址已被修改为“一级域名:// ”,再次返回到当前页面时,会出现空白页面的情况。这时把回调地址也置空。
// 刷新当前页面
let request: URLRequest = NSURLRequest.init(url: URL.init(string: redirect_url)!) as URLRequest
webView.load(request)
redirect_url = ""
3>在 URL Types 中添加一级域名,微信回调APP的时候使用